1

I could use some help. I am trying to color a bar chart assigning different colors using a foreach loop and pgfmathresult to get a color gradient. Here is a minimal example:

\documentclass{minimal}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\pgfplotstableread{
Label 1 2 3
R1 3 2 1
R2 2 1 3
R3 1 2 3
}\testdata

\begin{tikzpicture}
\begin{axis}[ybar stacked, ymin=0, xtick=data, xticklabels from table={\testdata}{Label}]
\foreach \s in {1,...,3}{
    \pgfmathparse{\s*30}
    \addplot [fill=blue!\pgfmathresult!green] table [y=\s, meta=Label,x expr=\coordindex] {\testdata};
}
\end{axis}
\end{tikzpicture}

\end{document}

But the result I obtain has no gradient

:enter image description here

Jet when I run almost the same code (without pgfplot):

\begin{tikzpicture}
\foreach \s in {1,...,3} {
    \pgfmathparse{(\s*30)}
 \draw[blue!\pgfmathresult!green, thick]
(0,\s * .2) -- (1,\s * .2)
;
}
\end{tikzpicture}

I get the desired gradient: enter image description here

Has anyone an idea whats going wrong here and how to fix it?

5

1 Answer 1

2

You need to expand pgfmathresult before passing it to \addplot. To inject the expanded value inside the command, one way is to use a common idiom LaTeX3 - Expand nested argument

(side note, addplot will eventually expand it, but only at the end; thus all the colors get expanded to the same value)

\def\plotcommand#1{
    \addplot [fill=blue!#1!green] table [y=\s, meta=Label,x expr=\coordindex] {\testdata};
}

\begin{tikzpicture}
\begin{axis}[ybar stacked, ymin=0, xtick=data, xticklabels from table={\testdata}{Label}]
\foreach \s in {1,...,3}{
    \pgfmathparse{\s*30}
    \expandafter\plotcommand\expandafter{\pgfmathresult}
}
\end{axis}
\end{tikzpicture}

Note

  1. I'm not that familiar with TikZ, maybe TikZ offer a built-in solution that is easier to read. On reading the questions below I'm pretty convinced that it isn't really possible to be cleaner.
  2. With a new LaTeX kernel you can \ExpandArgs{V}\plotcommand\pgfmathresult, see How do I have to invoke \expandafter for a macro with multiple arguments?
  3. If you put the plotcommand command definition inside the foreach you need to double the # because of some weird foreach command "bug" I can find Having trouble with Tikz and Beamer which is similar but not exactly the same
  4. If you don't mind using heavy package for a one-off task I'd recommend my package
\usepackage{execinside}

[... common preamble ...]


\begin{tikzpicture}
\begin{axis}[ybar stacked, ymin=0, xtick=data, xticklabels from table={\testdata}{Label}]
\foreach \s in {1,...,3}{
    \pgfmathparse{\s*30}
    \execinside{
        \addplot [fill=blue!\EIexpand\pgfmathresult!green] table [y=\s, meta=Label,x expr=\coordindex] {\testdata};
    }
}
\end{axis}
\end{tikzpicture}

Similar questions:

2
  • I don't think pgfplotsforeach is useful in this case because pgfmathresult is not directly substituted in.
    – user202729
    Apr 19, 2022 at 12:12
  • I just found out that the edef thing is an "official trick" recommended by pgf manual tex.stackexchange.com/questions/525053/… so even more likely for this one to be official.
    – user202729
    Jul 4, 2022 at 12:16

You must log in to answer this question.

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