4

I tried to parameterize my previous question, by defining a new command, however, the result isn't as I expected. So, what is wrong/missing here?

Additionally, since I need to apply this command to many plots with different y scales, how can I make the arrow height a percentage or fraction of the whole plot height instead of positioning it at certain y value?

\documentclass[border=1cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.14}
\usetikzlibrary{arrows.meta}
\tikzset{
    IntervalLine/.style={
        draw=black, 
        line width=1pt
    },
    IntervalArrow/.style={
    blue,
    very thick,
    {Stealth}-{Stealth}
    }
}


\newcommand{\AnnotateInterval}[3]{
    \begin{tikzpicture}
    \draw[IntervalLine] (#1, \pgfkeysvalueof{/pgfplots/ymin}) -- (#1, \pgfkeysvalueof{/pgfplots/ymax});
    \draw[IntervalLine] (#2, \pgfkeysvalueof{/pgfplots/ymin}) -- (#2, \pgfkeysvalueof{/pgfplots/ymax});
    \draw[IntervalArrow] (#1,2) -- node[above,align=center]{#3} (#2,2);
    \end{tikzpicture}
}


\begin{document}
    \begin{tikzpicture}
    \begin{axis}[xmin=0,xmax=5]
    \addplot[mark=none,blue] {x^2};
    \AnnotateInterval{2}{4}{some text}
    \end{axis}
    \end{tikzpicture}
\end{document}

enter image description here

Diaa
  • 9,599

1 Answers1

2

To make the output of your code more sensible, just remove \begin{tikzpicture} and \end{tikzpicture} from the \AnnotateInterval macro, as the comments have discussed.

If you want the arrow with text at a fraction of the height of the axis, you can for example use the approach in the below code, where I modified the \AnnotateInterval macro to take four arguments, instead of three, where the third is the the fractional height of the arrow.

rel axis cs: means that the following coordinates use relative axis coordinates, i.e. (0,0) is the lower left corner of the axis, and (1,1) is the upper right.

One thing you should be aware of: In the code you have \pgfplotsset{compat=1.14}. If the version specified here had been 1.10 or earlier, the macro as specified would not have worked properly inside the axis environment, because the coordinates would not have been corresponding to the axis values. To make the code work with earlier compat settings, you need to change the coordinates from (x,y) to (axis cs:x,y). Starting with compat=1.11, the default coordinate system is axis cs, so specifying it explicitly is not needed.

\documentclass[border=1cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.14}
\usetikzlibrary{arrows.meta}
\tikzset{
    IntervalLine/.style={
        draw=black, 
        line width=1pt
    },
    IntervalArrow/.style={
    blue,
    very thick,
    {Stealth}-{Stealth}
    }
}


\newcommand{\AnnotateInterval}[4]{
    \draw[IntervalLine] (#1, \pgfkeysvalueof{/pgfplots/ymin}) -- (#1, \pgfkeysvalueof{/pgfplots/ymax});
    \draw[IntervalLine] (#2, \pgfkeysvalueof{/pgfplots/ymin}) -- (#2, \pgfkeysvalueof{/pgfplots/ymax});
    \coordinate (tmp) at (rel axis cs:0,#3);
    \draw[IntervalArrow] (#1,2 |- tmp) -- node[above,align=center]{#4} (#2,2 |- tmp);
}


\begin{document}
    \begin{tikzpicture}
    \begin{axis}[xmin=0,xmax=5]
    \addplot[mark=none,blue] {x^2};
    \AnnotateInterval{2}{4}{0.2}{some text}
    \end{axis}
    \end{tikzpicture}
\end{document}
Torbjørn T.
  • 206,688
  • Many thanks. May I know the meaning of rel axis cs? or where can I find it in the manual? Additionally, number 2 in (#1,2 |- tmp) doesn't change the output when I change it another number. What does this 2 exactly do? – Diaa Apr 17 '17 at 16:00
  • @DiaaAbidou Most PDF reader have a search function, so finding it shouldn't be hard. But I edited my answer to say quickly what that means. – Torbjørn T. Apr 17 '17 at 16:03
  • 1
    @DiaaAbidou The 2 in that case is irrelevant. The coordinate specification (x,y |- u,v), is the same as (x,v), i.e. the x-value of the first coordinate and the y-value of the second is used. – Torbjørn T. Apr 17 '17 at 16:06
  • I appreciate your comprehensive response. – Diaa Apr 17 '17 at 16:07