3

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:
Thanks for the comments and answers. Now the \newcommand works. However, there is one problem left. The plot generated with the \newcommand with argument is slightly shifted up on the y axis.

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}

plots next to each other

I can't find the reason for the shift.

jmjr
  • 187
  • 1
  • 8

2 Answers2

10

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.

enter image description here

egreg
  • 1,121,712
  • 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 03 '17 at 01:46
2

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:

misaligned plots

Removing the spurious spaces fixes the issue.

aligned plots

\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.

cfr
  • 198,882