# Use TikZ foreach variable in node

This MWE

\documentclass{standalone}
\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}[scale=0.75]
\begin{axis}[ylabel=Y-Axis, xlabel=X-Axis
, xmin=2, xmax=10, ymin=0, ymax=12, clip=false, axis y line*=right]
\foreach \blah in {0.9,0.5,0.2,0.1,0.05,0.02,0.01,0.005}{
\addplot[mark=none, domain=2:10, thick] {-ln(\blah/x^2)/ln(x)} node [pos=0,left] {$c_2=$}; %Varying c_2 values
}
\end{axis}
\end{tikzpicture}

\end{document}


produces this result

Note that the c_2= nodes on the left-hand side have no values on by the equal sign. I thought I could fix that by using

\addplot[mark=none, domain=2:10, thick] {-ln(\blah/x^2)/ln(x)} node [pos=0,left] {$c_2=$\blah}; %Varying c_2 values


But this doesn't work because PDFLaTeX tells me that I have an "Undefined control sequence." while referring to \blah.

How can I get this to work?

-
add comment

## 3 Answers

PGFPlots includes a special looping mechanism that avoids problems with unexpanded macros:

\pgfplotsinvokeforeach{<list>}{
< code where the list element is available as #1 >
}


In your case, you would write

\pgfplotsinvokeforeach {0.9,0.5,0.2,0.1,0.05,0.02,0.01,0.005}{
\addplot[mark=none, domain=2:10, thick] {-ln(#1/x^2)/ln(x)} node [pos=0,left] {$c_2=#1$};
}


to get

-
Elegant, thanks, Jake! This is the last of three questions I've posted today. You've been a great resource on all of them. –  Richard Jul 18 '12 at 21:54
add comment

You can force \blah to be expanded before it goes out of scope:

\documentclass{standalone}
\usepackage{pgfplots}

\begin{document}

\def\doit#1{%
\addplot[mark=none, domain=2:10, thick] {-ln(#1/x^2)/ln(x)} node [pos=0,left] {$c_2=#1$}; %Varying c_2 values
}
\begin{tikzpicture}[scale=0.75]
\begin{axis}[ylabel=Y-Axis, xlabel=X-Axis
, xmin=2, xmax=10, ymin=0, ymax=12, clip=false, axis y line*=right]
\foreach \blah in {0.9,0.5,0.2,0.1,0.05,0.02,0.01,0.005}{
\expandafter\doit\expandafter{\blah}
}
\end{axis}
\end{tikzpicture}

\end{document}

-
This worked well, but it seems complex... is there no "simpler" solution? –  Richard Jul 18 '12 at 21:52
Well apparently yes see @Jake s answer, but he has an advantage over me of having used tikz before:-) Complexity is in the eye of the beholder... –  David Carlisle Jul 18 '12 at 21:54
add comment

I wonder why a direct expansion isn't used in this case. We see the syntax and what needs protection.

\begin{tikzpicture}[scale=0.75]
\begin{axis}[ylabel=Y-Axis,xlabel=X-Axis,xmin=2,
xmax=10,ymin=0,ymax=12,clip=false,axis y line*=right]
\foreach\x in {0.9,0.5,0.2,0.1,0.05,0.02,0.01,0.005}{%
\edef\x{\noexpand\addplot[mark=none,domain=2:10,thick]
{-ln(\x/x^2)/ln(x)}node[pos=0,left] {$c_2=\x$}}\x;
}
\end{axis}
\end{tikzpicture}


EDIT 2012/7/19

1. The problem Marc van Dongen has reported in his comment applies on my machine also to Jake's solution:

\begin{document}
\begin{tikzpicture}[scale=0.75]
\begin{axis}[ylabel=Y-Axis,xlabel=X-Axis,xmin=2,xmax=10,ymin=0,
ymax=12, clip=false, axis y line*=right]
\pgfplotsinvokeforeach{0.9,0.5,0.2,0.1,0.05,0.02,0.01,0.005}{%
\addplot[mark=none,domain=2:10,thick]{-ln(#1/x^2)/ln(x)}
node [pos=0,left] {$c_2=#1$};
}%
\end{axis}
\end{tikzpicture}
\end{document}


Maybe I have messed something up. I will allow Jake to confirm or disprove of this before posting a working example.

2. (Re)defining \x within a tikzpicture environment is harmless, provided the user knows what he is doing. \x isn't defined by TikZ itself.

Here is an example that works on my machine:

\begin{document}
% Style 1:
\begin{tikzpicture}
\begin{axis}
\foreach \am in {1,2,3}{%
\addplot{x^\am};
\addlegendentryexpanded{$x^\am$}
}
\end{axis}
\end{tikzpicture}

% Style 2:
\begin{tikzpicture}
\begin{axis}
\foreach \x in {1,2,3}{%
\edef\x{%
\noexpand\addplot{x^\x};
\noexpand\addlegendentry{$x^\x$}
}\x
}
\end{axis}
\end{tikzpicture}
\end{document}


-
This doesn't work for me. The labels ($c_2=\x$) for the graphs all end up at the bottom. Also, I'm worried about redefining \x in a tikzpicture. –  Marc van Dongen Jul 19 '12 at 4:40
Both code chunks work fine for me. Note that the node [pos=...] feature was only introduced in a relatively recent version of PGFPlots (1.5, I think), so maybe you're using an older version. –  Jake Jul 19 '12 at 18:24
Redefining \x is not harmless, even if the user knows what they're doing. The reason for this is that \x is a tikz primitive, which may be used by pgfplots. When implementation of tikz or pgfplots changes, code that worked before the change may not work after the change. –  Marc van Dongen Jul 20 '12 at 5:35
@MarcvanDongen: Please see my question at tex.stackexchange.com/questions/64065/is-x-a-primitive-anywhere. –  Ahmed Musa Jul 20 '12 at 12:24
@MarcvanDongen I'd be surprised if it were: the TikZ/PGF manual is full of \foreach\x. Skimming through /usr/local/texlive/2012/texmf-dist/tex/generic/pgfplots I find only similar uses of \x and no definition whatsoever. The same in /usr/local/texlive/2012/texmf-dist/tex/generic/pgf –  egreg Jul 20 '12 at 12:43
show 1 more comment