4

For the following, the variable \mystyle doesn't work as expected.

Therefore, how can I:

1- optimize the code by making three lists of values of \myalph, \mystyle, and \mylabel to be iterated over by foreach instead of typing the combinations one-by-one,

2- then fix the code to make \mystyle work as a line style option?

\documentclass{article}
\usepackage{pgfplots}

\begin{document}

\pgfplotsset{alph/.initial=1}
\newcommand*{\getalph}{\pgfkeysvalueof{/pgfplots/alph}} 

\begin{tikzpicture}[
  declare function = { CFDfixedalph(\time) = \time^(\getalph-1); } ]
\begin{semilogxaxis}
\foreach \myalph/\mylabel/\mystyle in {0.1/{one}/dashed , 0.5/{two}/solid , 0.9/{three}/red}{
    \addplot[alph=\myalph, domain = 1e-6 : 1e6, samples = 100, \mystyle] {CFDfixedalph(x)};
    \addlegendentryexpanded{\mylabel}
}
\end{semilogxaxis}
\end{tikzpicture}

\end{document}
6

There are well-known pitfalls with foreach loops in pgfplots, which are well explained in section 8.1 Utility Commands of the manual v1.16. This is why I am using \pgfplotsinvokeforeach and some \noexpand trickery. Notice that this is not the unique way to make it work, but a possible way which is easily extendible to more loop variables. Then I believe you got "cheated" in the answer to your previous question. Of course, not really cheated, because the answer is really great, right to the point and contains clear explanations. It is just that if I would want to solve the problem you have, I would just declare CFDfixedalph to be function of two variables, which it really is. Then you do not need any pgf keys trickery, just plug in the alpha value you like. Altogether the following works.

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}


\begin{tikzpicture}[
  declare function = { CFDfixedalph(\time,\alph) = \time^(\alph-1); } ]
\begin{semilogxaxis}
\edef\lstAlphs{0.1,0.5,0.9}
\edef\lstLabels{"one","two","three"}
\edef\lstStyles{"dashed","solid","red"}
\pgfplotsinvokeforeach{0,1,2}{
\pgfmathsetmacro{\myalph}{{\lstAlphs}[#1]} % <- CCB (carefully count braces)
\pgfmathsetmacro{\mystyle}{{\lstStyles}[#1]} 
\pgfmathsetmacro{\mylabel}{{\lstLabels}[#1]} 
 \edef\temp{\noexpand\addplot[domain = 1e-6 : 1e6, samples = 100,\mystyle]
    {CFDfixedalph(x,\myalph)};}
 \temp
 \addlegendentryexpanded{\mylabel}
}
\end{semilogxaxis}
\end{tikzpicture}
\end{document}

enter image description here

  • I highly appreciate your effort to explain the main issue. However, I would be grateful to explain to me this rookie inquiry: what is the meaning of code line \edef\temp{\noexpand...? and why did it end with temp before \addlegendentryexpanded? – Diaa Aug 27 '19 at 13:45
  • 1
    @Diaa This makes sure that first the arguments of \addplot are expanded, and then the \addplot command. Note that pgfplots comes with TeX-programming-notes.pdf, where this is explained better than I could explain it. – user194703 Aug 27 '19 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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