# tikzpicture as \newcommand with argument(s)

I have a tikz barplot which I want as a \newcommand with a variable. Depending on the variable, labels should be added or not. In the document I will use the plot several times, sometimes with, sometimes without labels. Thats why I want it as a command.

here my MWE:

\documentclass{article}
\usepackage{tikz, pgfplots}
\begin{document}

\newcommand{\myplotWithoutLabels}{
\begin{tikzpicture}
\begin{axis}[xbar, bar shift=0pt, bar width=20pt, xmin=0,
axis x line = none, axis y line* = middle,
ytick={1,2,3}, tickwidth=0, every tick/.style={draw=none},% label pos, no   tick marks
yticklabels={}
]
\addplot coordinates {(2,1)};
\addplot coordinates {(5,2)};
\addplot coordinates {(4,3)};
\end{axis}
\end{tikzpicture}
}

\myplotWithoutLabels

\newcommand{\myplotWithLabels}{
\begin{tikzpicture}
\begin{axis}[xbar, bar shift=0pt, bar width=20pt, xmin=0,
axis x line = none, axis y line* = middle,
ytick={1,2,3}, tickwidth=0, every tick/.style={draw=none},
yticklabels={L1, L2, L3}
]
\addplot coordinates {(2,1)};
\addplot coordinates {(5,2)};
\addplot coordinates {(4,3)};
\end{axis}
\end{tikzpicture}
}

\myplotWithLabels
\end{document}


I've tried several things, i.e.:

\newcommand{\myplot}[3]{
\begin{tikzpicture}
\begin{axis}[title=my Title,
xbar, bar shift=0pt, bar width=20pt, xmin=0,
axis x line = none, axis y line* = middle,
ytick={1,2,3}, tickwidth=0, every tick/.style={draw=none},
yticklabels={#1, #3, #3}
]
\addplot coordinates {(2,1)};
\addplot coordinates {(5,2)};
\addplot coordinates {(4,3)};
\end{axis}
\end{tikzpicture}
}

\myplot[L1,L2,L3]


or with only one (#1) argument. Neither did work.

The solution to this question Problem declaring newcommand with tikzpicture inside didn't help me either.

EDIT:

Here the code, I've put the two plots next to each other using subcaption package (\usepackage{subcaption}) to see the difference. The plots are both as \newcommand, one without argument, one with argument.

\newcommand{\myplot}[1]{
\begin{tikzpicture}
\begin{axis}[
xbar, bar shift=0pt, bar width=20pt, xmin=0,
axis x line = none, axis y line* = middle,
ytick={1,2,3}, tickwidth=0, every tick/.style={draw=none},
yticklabels={#1}
]
\addplot coordinates {(2,1)};
\addplot coordinates {(5,2)};
\addplot coordinates {(4,3)};
\end{axis}
\end{tikzpicture}
}

\begin{figure}[h!]
\centering
\begin{subfigure}[h!]{0.45\textwidth}
\myplotWithoutLabels
\end{subfigure}
\begin{subfigure}[h!]{0.45\textwidth}
\myplot{}
\end{subfigure}
\end{figure}


I can't find the reason for the shift.

• It should be yticklabels={#1,#2,#3} and \myplot{L1}{L2}{L3}. Or declare \myplot to have a single argument, coding yticklabels{#1}; then the call \myplot{L1,L2,L3} would be good. Mar 1, 2017 at 18:18
• To see how \newcommand works, consider reading How to create new commands with multiple arguments?
– Werner
Mar 1, 2017 at 19:03
• What egreg said works, for the version without label just write \myplot{}{}{}. Mar 1, 2017 at 20:57
• How is \myplotWithoutLabels defined? You don't want h! as the placement option for figure, but you really, really, really don't want it for subfigure where it makes no sense at all.
– cfr
Mar 3, 2017 at 1:25

## 2 Answers

You have two choices; which one depends very much on the application.

Remember that if you do

\newcommand{\foo}[3]{...}


then a call to \foo should be of the form

\foo{first}{second}{third}


where each argument is braced. It's not the same as in other programming language: the syntax \foo{first,second,third} would take first,second,third as #1 and TeX would look further for #2 and #3.

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

\newcommand{\myplotA}[3]{%
\begin{tikzpicture}
\begin{axis}[
xbar,
bar shift=0pt,
bar width=20pt,
xmin=0,
axis x line = none,
axis y line* = middle,
ytick={1,2,3},
tickwidth=0,
every tick/.style={draw=none},% label pos, no   tick marks
yticklabels={#1,#2,#3},
]
\addplot coordinates {(2,1)};
\addplot coordinates {(5,2)};
\addplot coordinates {(4,3)};
\end{axis}
\end{tikzpicture}%
}

\newcommand{\myplotB}[1]{%
\begin{tikzpicture}
\begin{axis}[
xbar,
bar shift=0pt,
bar width=20pt,
xmin=0,
axis x line = none,
axis y line* = middle,
ytick={1,2,3},
tickwidth=0,
every tick/.style={draw=none},% label pos, no   tick marks
yticklabels={#1},
]
\addplot coordinates {(2,1)};
\addplot coordinates {(5,2)};
\addplot coordinates {(4,3)};
\end{axis}
\end{tikzpicture}%
}

\begin{document}

\myplotA{L1}{L2}{L3}

\bigskip

\myplotB{L1,L2,L3}

\end{document}


As you see in the picture, the output is the same.

• I now realise that my code is identical to yours and that the only difference between yours and that in the OP's edit is that the OP removed your comment signs which I then put back. Not only is it an egreg answer, it is egreg's answer. Do you want to add some explanation and I delete mine?
– cfr
Mar 3, 2017 at 1:46

This is really an egreg answer, because egreg specialises in this ;).

Your definition introduces spurious spaces because you have not commented line endings which TeX interprets as spaces.

I don't know how your second definition is done, so I adapted your first to take an optional, rather than mandatory argument:

\documentclass{article}
\usepackage{subcaption,pgfplots}
\newcommand*{\myplot}[1][]{
\begin{tikzpicture}
\begin{axis}[
xbar,
bar shift=0pt,
bar width=20pt,
xmin=0,
axis x line = none,
axis y line* = middle,
ytick={1,2,3},
tickwidth=0,
every tick/.style={draw=none},
yticklabels={#1}
]
\addplot coordinates {(2,1)};
\addplot coordinates {(5,2)};
\addplot coordinates {(4,3)};
\end{axis}
\end{tikzpicture}
}
\begin{document}
\begin{figure}[h!]
\centering
\begin{subfigure}{0.45\textwidth}
\myplot
\end{subfigure}
\begin{subfigure}{0.45\textwidth}
\myplot[L1,L2,L3]
\end{subfigure}
\end{figure}
\end{document}


This reproduces the issue:

Removing the spurious spaces fixes the issue.

\documentclass{article}
\usepackage{subcaption,pgfplots}
\newcommand*{\myplot}[1][]{%
\begin{tikzpicture}
\begin{axis}[
xbar,
bar shift=0pt,
bar width=20pt,
xmin=0,
axis x line = none,
axis y line* = middle,
ytick={1,2,3},
tickwidth=0,
every tick/.style={draw=none},
yticklabels={#1}
]
\addplot coordinates {(2,1)};
\addplot coordinates {(5,2)};
\addplot coordinates {(4,3)};
\end{axis}
\end{tikzpicture}%
}
\begin{document}
\begin{figure}[h!]
\centering
\begin{subfigure}{0.45\textwidth}
\myplot
\end{subfigure}
\begin{subfigure}{0.45\textwidth}
\myplot[L1,L2,L3]
\end{subfigure}
\end{figure}
\end{document}


Note that I have removed the h! specifier from the subfigures because it makes no sense there and is not even defined, as far as I know. subfigure takes the same placement specifiers as minipage according to the manual.

I have not removed it from figure because it is defined there. However, you certainly should not use it. It never makes sense to give only h as the location specifier. If you really don't want the figure to more, don't use a float.