# pgfplotsinvokeforeach is invoked only twice

I would like to plot the family of curves with equation xy=c for several values of c. I also want each curve to be labeled with the value of c it corresponds to.

Here is my MWE:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin=-3.0,xmax=3.0,
ymin=-3.0,ymax=3.0,
axis x line=middle,
axis y line=middle,
axis equal image,
cycle list={blue}
]
\pgfplotsinvokeforeach{-3.0,-2.5,...,-0.5,0.5,1.0,...,3.0}{
\addplot+[domain=0.1:3] {#1/x} node[pos=0.5] {$#1$};
}
\end{axis}
\end{tikzpicture}
\end{document}


I get each curve plotted, but only two of them are labeled:

How do I get all twelve curves labeled?

-
Just remove the axis restrictions and you'll see them :-) pos=0.5 is not always in the visible range. –  percusse Sep 18 '12 at 13:57
@percusse: You are right, of course. Thanks for pointing that out. –  Matthew Leingang Sep 18 '12 at 14:15

To get finer control over the placement of the nodes, you could adapt my approach from Label plots in pgfplots without entering coordinates manually. For example, you could define a curved path and place all the labels at the intersections of their plot and the path:

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{intersections}

\pgfkeys{
/pgfplots/linelabel/.style={
name path global=labelpath,
execute at end plot={
\path [name path global = labelpositionline]
(rel axis cs:0.85,0) to [bend left=45, looseness=1] (rel axis cs:0.85,1);
\path [name intersections={of=labelpath and labelpositionline}] (intersection-1) node [font=\scriptsize] {#1};
},
}
}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin=-3.0,xmax=3.0,
ymin=-3.0,ymax=3.0,
axis x line=middle,
axis y line=middle,
axis equal image,
cycle list={blue}
]
\pgfplotsinvokeforeach{-3.0,-2.5,...,-0.5,0.5,1.0,...,3.0}{
}
\end{axis}
\end{tikzpicture}
\end{document}

-
Very cool. I was looking for an intersections solution but I was not able to refer to the plot by name. I was using name path instead of name path global and that must be the difference. –  Matthew Leingang Sep 19 '12 at 12:14

If you use a different value for pos, they will be visible:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin=-3.0,xmax=3.0,
ymin=-3.0,ymax=3.0,
axis x line=middle,
axis y line=middle,
axis equal image,
cycle list={blue}
]
\pgfplotsinvokeforeach{-3.0,-2.5,...,-0.5,0.5,1.0,...,3.0}{
\addplot+[domain=0.1:3] {#1/x} node[pos=0.92] {$#1$};
}
\end{axis}
\end{tikzpicture}
\end{document}


-
Wow, I hadn't thought to try that. Any idea why it doesn't work with 0.5? –  Matthew Leingang Sep 18 '12 at 14:11
Oh, wait. It might be that pos=0.5 is outside the window... –  Matthew Leingang Sep 18 '12 at 14:11
@MatthewLeingang yes ;-) –  Gonzalo Medina Sep 18 '12 at 14:12
Should have thought of that. I need a better way to place the nodes, then. –  Matthew Leingang Sep 18 '12 at 14:13
@MatthewLeingang You can play around with restrict y to domain=-4:4, to keep the plots stay in the visible range. –  percusse Sep 18 '12 at 14:22

As the first few commenters pointed out, the labels were placed, just outside the window defined by the pgfplots ymin/ymax keys.

My workaround was to alert the domain of each plotted function so that there were no points outside the window. Then pos=0.5 was exactly where I wanted it.

    \pgfplotsinvokeforeach{-3.0,-2.5,...,-0.5,0.5,1.0,...,3.0}{
\pgfmathsetmacro{\a}{abs(#1)/3}
\addplot+[domain=\a:3] {#1/x} node[black,fill=white,pos=0.5,sloped,inner sep=0pt] {$#1$};

The disadvantage is that if ymin or ymax were changed the line defining \a would need to be updated. So it's not optimal but the output is not bad.