pgf-tikz/pgfplots

\foreach does not work on text

Closed this issue · 3 comments

Hello,

when using a \foreach clause to generate and plot some functions I found some unexpected behaviour with how text/labels in the plot were handled.

Here is the code where I found the behaviour (I have not deleted some commented trials so that they are documented too):

\begin{tikzpicture}
	% Variables
	\newcommand\Nexp{n}
	\newcommand\Mexp{0.5}
	\newcommand\Acoeff{1}
	\newcommand\SIGMAMIN{5}
	\newcommand\SIGMAMAX{250}
	% Min Temp 100C
	\newcommand\TEMPMIN{100}
	% Max Temp 600C
	\newcommand\TEMPMAX{600}
	\begin{axis}[
		title={$\dot{\epsilon}_{cr} = \Acoeff \cdot \sigma^\Nexp \cdot e^{\left(-\displaystyle\frac{Q}{R\cdot T}\right)} \cdot t^{\Mexp}$},
		xlabel={$\sigma\ [MPa]$},
		ylabel={$T\ [\SI{}{\degreeCelsius}]$},
		ytick distance=100,
		zlabel={$\dot{\epsilon}_{cr}\ [s^{-1}]$},
		zmode=log,
		grid=major,
		colormap/viridis,
		%view={0}{90}, % View from the top
		colorbar,
		colorbar style={title={Log of $\dot{\epsilon}_{cr}$},
			ytick distance=5,
			every axis,},
		cycle list name=color,
		]
		\foreach \i in {0,2,...,10} {
			\addplot3 [
				%contour lua={number=20,labels=false},
				%thick,
				surf,
				%shader=interp,
				%contour gnuplot={levels={1e-10}},
				domain=\SIGMAMIN:\SIGMAMAX,
				y domain=\TEMPMIN:\TEMPMAX,
				samples=30,
				]
				{\Acoeff*x^\i*exp(-197000/(8.314*(y+273.15)))};
				% Add label
			\addplot3 [
				mark=*,
				red,
				point meta=explicit symbolic,
				nodes near coords={$n=\text{\i}$}
				] 
				coordinates {
				(\SIGMAMAX,
				\TEMPMAX,
				{\Acoeff*\SIGMAMAX^\i*exp(-197000/(8.314*(\TEMPMAX+273.15)))}
				)};%[$n=\text{\i}$];
%				node [pin=left:{n=\text{\i}}] at (\SIGMAMAX, \TEMPMAX, {\Acoeff*\SIGMAMAX^\i*exp(-197000/(8.314*(\TEMPMAX+273.15)))}) {};
				
%				\node [coordinate, pin=left:{n=\text{\i}}] at (\SIGMAMAX, \TEMPMAX, {\Acoeff*\SIGMAMAX^\i*exp(-197000/(8.314*(\TEMPMAX+273.15)))}) {};

%			\draw [blue, fill] (\SIGMAMAX, \TEMPMAX, {\Acoeff*\SIGMAMAX^\i*exp(-197000/(8.314*(\TEMPMAX+273.15)))}) circle (2pt) node [right] {$n=\text{\i}$}
		}%
	\renewcommand{\i}{3}
				\addplot3 [
	mark=*,
	red,
	point meta=explicit symbolic,
	nodes near coords={$n=\text{\i}$}
	] 
	coordinates {
		(\SIGMAMAX,
		\TEMPMAX,
		{\Acoeff*\SIGMAMAX^\i*exp(-197000/(8.314*(\TEMPMAX+273.15)))}
		)};
	\renewcommand{\i}{9}
	\addplot3 [
	mark=*,
	red,
	point meta=explicit symbolic,
	nodes near coords={$n=\text{\i}$}
	] 
	coordinates {
		(\SIGMAMAX,
		\TEMPMAX,
		{\Acoeff*\SIGMAMAX^\i*exp(-197000/(8.314*(\TEMPMAX+273.15)))}
		)};
		\pgfplotsforeachungrouped \i in {0,2,...,10} {
		}%
	\end{axis}
\end{tikzpicture}

If the code above is run, the text nodes near coords={$n=\text{\i}$} will print out "n=12", which is obviously wrong. 12 would be the next iteration of the loop if it continued. Notice that I modify the value of \i manually after the loop and print out a couple of other points, but the text is still wrong. The surprising case was that the points and the plots are displayed correctly.

I asked in the latex IRC channel and I was told to try:

\expanded{\noexpand\addplot3 [ mark=*, red, point meta=explicit symbolic, nodes near coords={$n=\noexpand\text{\i}$} ] 				coordinates {
						(\SIGMAMAX,
						\TEMPMAX,
						{\Acoeff*\SIGMAMAX^\i*exp(-197000/(8.314*(\TEMPMAX+273.15)))}
						)};}

Which did work.

The conclusion we arrived is that text inside the \addplot command is somehow cached and used with the last value available. In this case (and probably most) this is incorrect behavious; or at least, unexpected.

I do not know if \addplot can be changed or even if it should, but at least I think it would be a good thing to document this issue in the documentation, along with the other issues/limitations/fixes.

I was surprised that I could not find anybody commenting anything on this. I would have expected someone to have already hit this behaviour, as it is "common" in parametric plots.

Either way, thank you for your impressive work.

Best regards,
Fer

This has been asked hence answered several times on tex.stackexchange.com, see for example this answer posted by the pgfplots author Christian Feuersänger in 2012.

The limitation of \foreach is more or less already documented in the pgfplots manual (v1.18.1), sec. 8.1 "Utility Commands", in doc for \pgfplotsinvokeforeach. I admit it's not obvious enough.

@muzimuzhi thank you for your reply. I had read and tried \pgfplotsforeachungrouped and I had also read \pgfmathparse... Shame on me, I skipped the solution... It also goes to show that my search-engine-fu is not that good... :/

But maybe a comment on the issue would be appreciated :) Since this is not an expected behaviour... Maybe at the top :)

Either way, I will close the issue since it has been answered.

Thank you for your time and help! Regards,
Fer

Please read the manual. There you will find \pgfplotsinvokeforeach.

The issue tracker is also not for Q&A. Please use the community forums, e.g. https://tex.stackexchange.com/