# PGFplots within Environ format mistake

I try to write an environment for a simple barplot with pgfplots to reduce the needed markup. For that I use the environ package.

For some reason tikz complains about a format mistake at the provided coordinates.

MWE:

\documentclass[varwidth=true, border=2pt]{standalone}

\usepackage{pgfplots}
\usepackage{environ}

\NewEnviron{barplot}{%
\begin{tikzpicture}
\begin{axis}[
symbolic x coords={A, B, C},
xtick=data,
ymax=40,
ymajorgrids=true
]
\BODY
};
\end{axis}
\end{tikzpicture}
}

\begin{document}

\begin{barplot}
(A, 10)(B, 20)(C, 30)
\end{barplot}

\end{document}

• I don't have any problems with the code. I have pgfplots v1.12 and TikZ v3.0.0. What is the complaint on your case? – percusse May 29 '15 at 9:23
• @percusse Thanks for your reply. Indeed, my pgfplots version was v1.8. After I updated it, the code works. – Jan Trienes May 29 '15 at 9:36

If an older pgfplots wants to see an expanded coordinate list rather than a coordinate list in a macro, then it can be expanded with lots of \expandafter or the following way:

\documentclass[varwidth=true, border=2pt]{standalone}

\usepackage{pgfplots}
\usepackage{environ}

\NewEnviron{barplot}{%
\begin{tikzpicture}
\begin{axis}[
symbolic x coords={A, B, C},
xtick=data,
ymax=40,
ymajorgrids=true
]
\edef\processme{%
\BODY
};%
}\processme
\end{axis}
\end{tikzpicture}% comment to remove unwanted space
}

\begin{document}

\begin{barplot}
(A, 10)(B, 20)(C, 30)
\end{barplot}

\end{document}


Better variant of egreg, which does not expand the cell entries:

\documentclass[varwidth=true, border=2pt]{standalone}

\usepackage{pgfplots}
\usepackage{environ}

\NewEnviron{barplot}{%
\def\process##1{%
\addplot[ybar, fill=gray] coordinates {##1};
}%
\begin{tikzpicture}
\begin{axis}[
symbolic x coords={A, B, C},
xtick=data,
ymax=40,
ymajorgrids=true
]
\expandafter\process\expandafter{\BODY}
\end{axis}
\end{tikzpicture}%
}

\begin{document}

\begin{barplot}
(A, 10)(B, 20)(C, 30)
\end{barplot}

\end{document}


Instead of \BODY, package environ also offers an interface with \collect@body:

\documentclass[varwidth=true, border=2pt]{standalone}

\usepackage{pgfplots}
\usepackage{environ}

\makeatletter
\newenvironment{barplot}{%
\collect@body\process@barplot
}{}
\def\process@barplot#1{%
\begin{tikzpicture}
\begin{axis}[
symbolic x coords={A, B, C},
xtick=data,
ymax=40,
ymajorgrids=true
]
\addplot[ybar, fill=gray] coordinates {#1};
\end{axis}
\end{tikzpicture}%
}
\makeatother

\begin{document}

\begin{barplot}
(A, 10)(B, 20)(C, 30)
\end{barplot}

\end{document}


As percusse said, with pgfplots v1.12 and TikZ v3.0, the expansion tricks are not needed.

• Shouldn't \noexpand\BODY be \BODY? Or am I missing something? – egreg May 29 '15 at 9:47
• By the way, I'd do \def\processme##1{\addplot[ybar,fill=gray] coordinates {##1}} before \begin{tikzpicture} and \expandafter\processme\expandafter{\BODY}; where you do the \edef. – egreg May 29 '15 at 9:52
• @egreg Yes, plain \BODY. The \noexpand was a left-over from a test. – Heiko Oberdiek May 29 '15 at 9:54
• @egreg Yes, \process is better, because this method does not expand the cell entries. Also I have added a variant with interface \collect@body. – Heiko Oberdiek May 29 '15 at 10:26