19

Please have a look at the following MWE:

\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            %ymode=log,
        ]
            \addplot coordinates {
            (0, 6.887e-02)
            (0.5, 3.177e-02)
            (1, 1.341e-02)
            (1.5, 5.334e-03)
            (2, 2.027e-03)
            (2.5, 7.415e-04)
            (3, 2.628e-04)
            (3.5, 9.063e-05)
            (4, 3.053e-05)
            };
            \draw (axis cs:1.2,\pgfkeysvalueof{/pgfplots/ymin}) -- (axis cs:1.2,\pgfkeysvalueof{/pgfplots/ymax});
        \end{axis}
    \end{tikzpicture}
\end{document}

It produces a graph like this (some data with a vertical line at x=1.2):

some data with a vertical line at x=1.2

As soon as I uncomment ymode=log, the vertical line disappears. Bummer!

Fabian
  • 809

2 Answers2

22

You can use \draw ({axis cs:1.2,0}|-{rel axis cs:0,0}) -- ({axis cs:1.2,0}|-{rel axis cs:0,1}) to draw the vertical line from the top of the plot area to the bottom. This command looks a bit intimidating at first, but it's really not that bad:

The point rel axis cs:0,0 is the lower left corner of the plot area, rel axis cs:0,1 is the upper left corner. The syntax (A|-B) specifies the point that lies at the intersection of a vertical line through A and a horizontal line through B (put another way, we're using the x coordinate of A and the y coordinate of B). When using axis cs and rel axis cs in the coordinate specification, they need to be grouped in {...} to hide the commas.

\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            ymode=log,
        ]
            \addplot coordinates {
            (0, 6.887e-02)
            (0.5, 3.177e-02)
            (1, 1.341e-02)
            (1.5, 5.334e-03)
            (2, 2.027e-03)
            (2.5, 7.415e-04)
            (3, 2.628e-04)
            (3.5, 9.063e-05)
            (4, 3.053e-05)
            };
            \draw ({axis cs:1.2,0}|-{rel axis cs:0,1}) -- ({axis cs:1.2,0}|-{rel axis cs:0,0});
        \end{axis}
    \end{tikzpicture}
\end{document}
Jake
  • 232,450
  • It's strange that I can't make \pgfmathparse{pow(10,\pgfkeysvalueof{/pgfplots/ymax})} work to get back the original value. – percusse May 22 '12 at 13:05
  • 1
    @percusse: You can get them back with \pgfplotsextra{ \pgfmathsetmacro\ymin{exp(\pgfkeysvalueof{/pgfplots/ymin})} \pgfmathsetmacro\ymax{exp(\pgfkeysvalueof{/pgfplots/ymax})} \draw (axis cs:1.2,\ymin) -- (axis cs:1.2,\ymax); }, but there seems to be a numerical error (the line doesn't go all the way to the bottom), and it's a bit too labour intensive for my liking. – Jake May 22 '12 at 14:05
  • Indeed it is but still it would have been great to have yminlog and ymaxlog keys to get it running for semilogyaxis environment etc. – percusse May 22 '12 at 14:24
  • @percusse you are right; that should probably be fixed... on first sight, it seems as if exp() should be applied by pgfplots when it defines the /pgfplots/ymin limits... – Christian Feuersänger May 22 '12 at 20:15
  • 2
    @Jake the approach with pgfmathsetmacro uses pgf math - which is unsuitable for such data ranges. Using something with extended precision (like /pgf/fpu) would solve the issue. Keep in mind that \pgfmathsetmacro will always assign the result to some TeX register (for whatever reason). Thus, /pgf/fpu + \pgfmathparse{...}\let\ymin=\pgfmathresult would fix your code snippet. – Christian Feuersänger May 22 '12 at 20:16
  • @ChristianFeuersänger: Ah yes, that makes sense. Thanks for the explanation. – Jake May 22 '12 at 20:18
  • @ChristianFeuersänger Actually I tried fpu but it was still off. Maybe I wasn't careful enough. – percusse May 22 '12 at 20:24
2

With PGFPlots 1.11 or later, Jake's solution could be made a little less intimidating with the following equivalent syntax.

\draw (1.2,0 |- current axis.south) -- (1.2,0 |- current axis.north);

Since that version, axis cs has been the default and therefore can be omitted. I find TikZ's anchors (a property of any node, of which a PFGPlots axis is one) easier to use than rel axis cs. Without coordinate specifiers, there's no need for braces.

\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
\pgfplotsset{compat=1.11} % <=== or later
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            ymode=log,
        ]
            \addplot coordinates {
            (0, 6.887e-02)
            (0.5, 3.177e-02)
            (1, 1.341e-02)
            (1.5, 5.334e-03)
            (2, 2.027e-03)
            (2.5, 7.415e-04)
            (3, 2.628e-04)
            (3.5, 9.063e-05)
            (4, 3.053e-05)
            };
            \draw (1.2,0 |- current axis.south) -- (1.2,0 |-
            current axis.north);
        \end{axis}
    \end{tikzpicture}
\end{document}
bongbang
  • 385