Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Any idea, why the following doesn't work and how to fix ist:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots}


\begin{document}
\begin{tikzpicture}
\begin{axis}[no markers]
   \pgfmathsetmacro{\i}{0}
   \foreach \f in {sin(deg(x)),x^2}
   {
   \addplot  {\f} node [pos=0.6,right] {\i};
   \pgfmathsetmacro{\i}{\i+1};
   }
\end{axis}
\end{tikzpicture}

\end{document}

I get the following output:

output

Edit:

I want that the value of \i in my loop is the same for one pass of the loop regardless if I use \i for a node or something else (which may be related to expanding problems), at the end of the loop I want to set a new value of \i.

Or to say it in other words: I just want to use the variable \i as one would do it in other programming languages inside a loop...

share|improve this question
    
Do you just want to number the plots, or will you need a more elaborate math expression for \i in your real application? –  Jake Sep 24 '12 at 17:45
    
No it's not about numbering the plots. Yes I also want to use a more elaborate math expression. However the aim of the question is more about just to understand why the iteration doesn't work and how I can fix it, its more about learning about how to "program" in LaTeX rather than solving a particular problem like numbering plots or something like that... –  student Sep 24 '12 at 17:51
    
If I understand the problem (it would help if you explained what you wanted to happen), this is because the interior of the foreach is inside a group so the assignment of \i is reset each time around the loop. You could put \global\let\i=\i to make it have effect outside. If you want integers, use \pgfmathtruncatemacro instead of \pgfmathsetmacro. –  Andrew Stacey Sep 24 '12 at 17:54
    
@AndrewStacey: That's only part of the problem. The resetting issue could be solved by using \pgfplotsforeachungrouped instead of \foreach, but another issue is that the node content is not expanded at the time of the definition, but only at the time of drawing (after the plot is finished), so all nodes would have the same value (the final value of \i). –  Jake Sep 24 '12 at 17:58
    
Yes, the main problem is, that \i seems not to change it's value... –  student Sep 24 '12 at 18:00
add comment

1 Answer

up vote 4 down vote accepted

There are two issues at play here:

  1. The assignment of \i is local to the group introduced by \foreach, so \i is reset for each iteration. You can solve this by replacing \foreach with \pgflotsforeachungrouped, which doesn't introduce grouping.
  2. The content of the node is not expanded, but saved as \i. Nodes (and other TikZ drawing commands) in an axis environment aren't drawn immediately, but only after the axis is complete (otherwise it wouldn't be clear where to place the node). So with the current code, you'd end up with two nodes reading 2.0 (the final value of \i after two iterations). PGFPlots stores the node commands in the way they were defined, so you have two nodes containting \i, which are executed at the end of the plot, when the value of \i is 2.0.

    To make the node use the value of \i at the time the \addplot command was called, you can replace \addplot ... with

    \edef\doplot{\noexpand\addplot  {\f} node [pos=0.6,right] {\i};}
    \doplot
    

    What this does is create a new macro called \doplot, which contains \addplot {<content of \f>} node [pos=0.6, right] {<content of \i>}, so the two macros \f and \i have been expanded (hence the name *e*def). The \addplot command shouldn't be expanded, so we're protecting it using \noexpand.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots}


\begin{document}
\begin{tikzpicture}
\begin{axis}[no markers]
   \pgfmathsetmacro{\i}{0}
   \pgfplotsforeachungrouped \f in {sin(deg(x)),x^2}
   {
       \pgfmathsetmacro{\i}{\i+1};
       \edef\doplot{\noexpand\addplot  {\f} node [pos=0.6,right] {\i};}
       \doplot
   }
\end{axis}
\end{tikzpicture}

\end{document}
share|improve this answer
    
Thanks, that does what I want! Could you explain the line with \edef in some more detail? –  student Sep 24 '12 at 18:18
    
@student: I've edited my answer to provide a bit more of an explanation. –  Jake Sep 24 '12 at 18:27
    
thanks very much, now I think it it clear! –  student Sep 24 '12 at 18:31
    
@student: Cool! Expansion issues are a bit confusing, so you might have to read up on \let, \def, \edef, \noexpand and \expandafter a bit. –  Jake Sep 24 '12 at 18:35
    
@jake: Please which version of pgfplots have you used? I get a slightly different output. The numbers 1.0 and 2.0 are superimposed on each other. Also, why didn't you use count key? \foreach [count=\fc] \f in {sin(deg(x)),x^2}{\global\let\fc\fc\addplot {\f} node [pos=0.6,right] {\fc};}. –  Ahmed Musa Sep 25 '12 at 21:37
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.