Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

In the plot below I would like to add two vertical lines at $x = \frac{\pi}{15} \pm \frac{1}{20}$. How can I do that?

f[x_] := (x^2 z)/((x^2 - y^2)^2 + 4 q^2 x^2) /. {y -> π/15, z -> 1, q -> π/600}
Plot[{f[x], f[π/15],f[π/15]/Sqrt[2]}, {x, π/15 - .01, π/15 + .01}]

Plot

share|improve this question
2  
Are you sure you want +-1/20? This is outside your current plot range. –  Ajasja Mar 27 '12 at 10:18
    
A related question. –  J. M. Jun 4 '13 at 6:48
add comment

6 Answers

up vote 30 down vote accepted

An easy way to add a vertical line is by using Epilog.

Here is an example:

f[x_] := (x^2 z)/((x^2 - y^2)^2 + 4 q^2 x^2) /. {y -> π/15, z -> 1, q -> π/600}
Quiet[maxy = FindMaxValue[f[x], x]*1.1]
lineStyle = {Thick, Red, Dashed};
line1 = Line[{{π/15 + 1/50, 0}, {π/15 + 1/50, maxy}}];
line2 = Line[{{π/15 - 1/50, 0}, {π/15 - 1/50, maxy}}];
Plot[{f[x], f[π/15], f[π/15]/Sqrt[2]}, {x, π/15 - 1/20, π/15 + 1/20},
    PlotStyle -> {Automatic, Directive[lineStyle], Directive[lineStyle]},
    Epilog -> {Directive[lineStyle], line1, line2}]

Vertical lines added

Caveat

While adding lines as Epilog (or Prolog) objects works most cases, the method can easily fail when automated, for example by automatically finding the minimum and maximum of the dataset. See the following examples where the red vertical line is missing at $x=5$:

data1 = Table[0, {10}];
data2 = {1., 1., 1.1*^18, 1., 6., 1.2, 1., 1., 1., 148341.};

Row@{
  ListPlot[data1, Epilog -> {Red, Line@{{5, Min@data1}, {5, Max@data1}}}],
  ListPlot[data2, Epilog -> {Red, Line@{{5, Min@data2}, {5, Max@data2}}}]
  }

enter image description here

In the left case, Min and Max of data turned out to be the same, thus the vertical line has no height. For the second case, Mathematica fails to draw the line due to automatically selected PlotRange (selecting PlotRange -> All helps). Furthermore, if the plot is part of a dynamical setup, and the vertical plot range is manipulated, the line endpoints must be updated accordingly, requiring extra attention.

Solution

Though all of these cases can be handled of course, a more convenient and easier option would be to use GridLines:

Plot[{f[x]}, {x, π/15 - 1/20, π/15 + 1/20},
    GridLines -> {{π/15 + 1/50 π/15 - 1/50}, {f[π/15], f[π/15]/Sqrt[2]}}, PlotRange -> All]

enter image description here

And for the extreme datasets:

Row@{
  ListPlot[data1, GridLines -> {{{5, Red}}, None}],
  ListPlot[data2, GridLines -> {{{5, Red}}, None}]
  }

enter image description here

share|improve this answer
    
@Istvan thanks for the edit. –  Ajasja Jun 4 '13 at 12:56
    
Welcome Ajasja. A certain data2 & Epilog combo pissed me off recently triggering this edit. Sadly, I can't give a sound explanation on why Mathematica fails to draw the Line in that case. Perhaps someone else has an insight on this. –  István Zachar Jun 4 '13 at 16:03
    
In the Epilog version, I'd personally use Scaled[] instead of futzing around with bounds. Witness for instance ListPlot[{1., 1., 1.1*^18, 1., 6., 1.2, 1., 1., 1., 148341.}, Epilog -> {Blue, Line[{Scaled[{0, -1}, {5, 0}], Scaled[{0, 1}, {5, 0}]}]}]. –  J. M. Jun 5 '13 at 11:26
    
@0x4A4D Yes, I was about to add that (even before István's edit). The problem is that only the y coordinate should be scaled not the x. And {x, Scaled[y]} is not valid. –  Ajasja Jun 5 '13 at 12:35
    
I'm not scaling the $x$-coordinate in what I'm proposing. Look at the output carefully. Also look up the two-argument form of Scaled[]. –  J. M. Jun 5 '13 at 12:36
show 2 more comments

Next possibility is to use ListPlot:

gp1 = Plot[{({f[x], f[π/15], f[π/15]/Sqrt[2]},{x, π/15 - .05, π/15 + .05}];

ymax = Max[Last /@ Level[Cases[%, _Line, Infinity], {-2}]];

gp2 = ListPlot[{{{π/15 - 1/20, 0}, {π/15 - 1/20,ymax}}, {{π/15 + 1/20, 0}, {π/15 + 1/20, ymax}}},
Joined -> True, PlotRange -> {{0.15, 0.26}, All}];
Show[{gp1, gp2}]
share|improve this answer
    
You might want to note how I formatted your previous answer, and apply that formatting to this answer... –  J. M. Jun 4 '13 at 7:11
    
You may also find it valuable to register your account. –  rcollyer Jun 4 '13 at 12:47
add comment

Another possibility is to use Ticks:

Plot[{f[x], f[π/15], f[π/15]/Sqrt[2]}, {x, π/15 - .06, π/15 + .06},
     Ticks -> {{{π/15 + 1/20, π/15 + 1/20, {0.595, 0}, Directive[Red, Dashed]},
                {π/15 - 1/20, π/15 - 1/20, {0.595, 0}, Directive[Blue, Dashed]}},
                All}, PlotRange -> {{0.12, 0.3}, All}]
share|improve this answer
    
Clever manipulation of the Ticks specification, +1. –  rcollyer Jun 4 '13 at 12:47
add comment

Another possibility is to use ParametricPlot in tandem with Show:

Show[{
  Plot[{f[x], f[Pi/15], f[Pi/15]/Sqrt[2]}, {x, 0.1, 0.3}, 
   PlotRange -> All, Frame -> True, Axes -> False],

  ParametricPlot[{{Pi/15 + 1/20, u}, {Pi/15 - 1/20, u}}, {u, 0, 9000},
    PlotStyle -> Black]
  }]

ParametricPlot

share|improve this answer
add comment

Can use Show, but Epilog is better.

f[x_] := (x^2 z)/((x^2 - y^2)^2 + 4 q^2 x^2) /. {y -> π/15, z -> 1, q -> π/600}
plot = Plot[{f[x], f[π/15], 
    f[π/15]/Sqrt[2]}, {x, π/15 - .01, π/15 + .01}, PlotRange -> {{0, 0.26}, Automatic}];

Show[plot, 
 Graphics[{Black, Line[{{Pi/15 + 1/20, 2000}, {Pi/15 + 1/20, 9000}}]}],
 Graphics[{Black, Line[{{Pi/15 - 1/20, 2000}, {Pi/15 - 1/20, 9000}}]}]]

enter image description here

share|improve this answer
add comment

One way is to use GridLines:

f[x_] := (x^2 z)/((x^2 - y^2)^2 + 4 q^2 x^2) /. {y -> π/15, z -> 1, q -> π/600}

Plot[f[x], {x, π/15 - .1, π/15 + .1}, 
 GridLines -> {{Pi/15 - 1/20, Pi/15 + 1/20}, {f[Pi/15], f[Pi/15]/Sqrt[2]}}, 
 PlotRange -> All, Frame -> True, Axes -> False]

Mathematica graphics

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.