2

I'm trying to build a bar graph using \foreach.I'd like to have each bar colored based on a variable defined. (this is part of a broader project, so I can't change how they are defined.)

Using the \count macro to have the index value at each iteration, I'd like to use it to choose the correct color of the bar. But the macro \n (which is the index) is taken as is, and not its value. Hence I get an error about Undefined color 'color@\n'.

I've checked by using typeout that the value is correct, it's just that it doesn't seem to be a string or something...

Here is a MWE :

\documentclass{article}
\usepackage{tikz,pgfplots,pgffor}

\colorlet{color@1}{green} \colorlet{color@2}{yellow} \colorlet{color@3}{orange} \colorlet{color@4}{red}

\begin{document} \begin{tikzpicture} \begin{axis}[ xtick={1,...,4}, x tick style={draw=none}, xticklabel={1}, ymin=0, every axis plot/.append style={ybar,fill} ] \foreach \x [count=\n] in {1,3,2,10}{ \typeout{index is \n} \addplot[color=color@\n ] coordinates {(\n,\x)}; % Here is the error about color@\n undefined. } \end{axis} \end{tikzpicture}

\tikz[x=0.75cm,y=0.75cm] \foreach \x [count=\xi] in {a,...,d} \foreach \y [count=\yi] in {\x,...,d} \node [draw, top color=white, bottom color=color@\xi, minimum size=0.666cm] at (\xi,-\yi) {$\xi,\yi$};

\end{document}

The second example is working perfectly well and is adapted from the documentation. I don't see where the error is in the first example.

MWE result

Could it be an expansion error ?

Many thanks

3isenHeim
  • 2,107

1 Answers1

2

The expansion of the optional argument to \addplot was definitely quite finicky. In the end, I use a listofitems list to define and expand the colors. See ADDENDUM for version without listofitems.

\documentclass{article}
\usepackage{tikz,pgfplots,pgffor,listofitems}
\pgfplotsset{compat=1.17}
\readlist\colorlist{green,yellow,orange,red}

\begin{document} \begin{tikzpicture} \begin{axis}[ xtick={1,...,4}, x tick style={draw=none}, xticklabel={1}, ymin=0, every axis plot/.append style={ybar,fill} ] \readlist\mylist{1,3,2,10} \foreachitem \x \in \mylist[]{ \typeout{index is \xcnt} \edef\tmp{color=\colorlist[\xcnt]} \expandafter\addplot\expandafter[\tmp] coordinates {(\xcnt,\x)}; } \end{axis} \end{tikzpicture}

\tikz[x=0.75cm,y=0.75cm] \foreach \x [count=\xi] in {a,...,d} \foreach \y [count=\yi] in {\x,...,d} \node [draw, top color=white, bottom color={\colorlist[\xi]}, minimum size=0.666cm] at (\xi,-\yi) {$\xi,\yi$};

\end{document}

enter image description here

ADDENDUM

Version without using listofitems. In both cases, the key is expanding the color before presenting it to the \addplot, by way of

        \edef\tmp{color=color@\n}
        \expandafter\addplot\expandafter[\tmp] 
           coordinates {(\n,\x)};

The MWE:

\documentclass{article}
\usepackage{tikz,pgfplots,pgffor}
\colorlet{color@1}{green}
\colorlet{color@2}{yellow}
\colorlet{color@3}{orange}
\colorlet{color@4}{red}

\begin{document} \begin{tikzpicture} \begin{axis}[ xtick={1,...,4}, x tick style={draw=none}, xticklabel={1}, ymin=0, every axis plot/.append style={ybar,fill} ] \foreach \x [count=\n] in {1,3,2,10}{ \typeout{index is \n} \edef\tmp{color=color@\n} \expandafter\addplot\expandafter[\tmp] coordinates {(\n,\x)}; } \end{axis} \end{tikzpicture}

\tikz[x=0.75cm,y=0.75cm] \foreach \x [count=\xi] in {a,...,d} \foreach \y [count=\yi] in {\x,...,d} \node [draw, top color=white, bottom color=color@\xi, minimum size=0.666cm] at (\xi,-\yi) {$\xi,\yi$};

\end{document}