7

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

Graph showing unlabeled c_2 values

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?

3 Answers 3

11

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

1
  • 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
    Commented Jul 18, 2012 at 21:54
6

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}
2
  • This worked well, but it seems complex... is there no "simpler" solution?
    – Richard
    Commented Jul 18, 2012 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... Commented Jul 18, 2012 at 21:54
0

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.

enter image description here

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}

enter image description here

6
  • 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.
    – user10274
    Commented Jul 19, 2012 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
    Commented Jul 19, 2012 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.
    – user10274
    Commented Jul 20, 2012 at 5:35
  • @MarcvanDongen: Please see my question at tex.stackexchange.com/questions/64065/is-x-a-primitive-anywhere.
    – Ahmed Musa
    Commented Jul 20, 2012 at 12:24
  • 1
    @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
    Commented Jul 20, 2012 at 12:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .