7

My particular question involves TikZ/pgfplots (see MWE below) but I suppose a more general solution exists (or does not exist for a deep reason that I could not find).

I wish to predefine some value and pass it later on in the options of an environment (in my case, the xtick or/and xticklabels of the axis environment of tikzfigure).

I have read a few related questions (the closest is Passing a macro to a vector declaration in tikz/pgf but I failed to make the accepted solution work for my case). I suppose the issue is that LateX expands macros as it reads them (correct me if I'm wrong) which means that \begin{someenvironment}[option1=\mymacro] will try to pass the string \mymacro to option1 (and not care that it starts with a backslash, or care too late).

I roughly understand how the \foo\bar syntax is fixed by \expandafter\foo\bar but I could not get any similar trick to work, no matter how much of \begin{axis}[xticklabels= I prefaced with expandafters -

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\usepackage{pgfplots} 


\begin{document}

    %The figure I want to obtain (but without giving "A1,A2,A3" explicitly)
    \begin{tikzpicture}
    \begin{axis}[
    xmin=0,xmax=10,
    ymin=0,ymax=4,
    xtick={1,4,7},
    xticklabels={A1,A2,A3},
    ytick=\empty
    ]

    \addplot+[domain=0:10,samples=100,no markers]{sqrt(x)};

    \end{axis}

    \end{tikzpicture}

    % This fails to do what I want, as the commas are not understood as value separators
    \begin{tikzpicture}
    \newcommand{\tiklist}{A1,A2,B}
    \begin{axis}[
    xmin=0,xmax=10,
    ymin=0,ymax=4,
    xtick={1,4,7},
    xticklabels={\tiklist},
    ytick=\empty
    ]

    \addplot+[domain=0:10,samples=100,no markers]{sqrt(x)};

    \end{axis}

    \end{tikzpicture}

\end{document}

Compilation output: two figures

7

You can force expansion via the .expanded handler of pgfkeys (section 82.4.6 "Expanded and Multiple Values", p. 890, pgfmanual, v3.0.1a).

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots} 

\begin{document}

    \begin{tikzpicture}
    \newcommand{\tiklist}{A1,A2,B}
    \begin{axis}[
    xmin=0,xmax=10,
    ymin=0,ymax=4,
    xtick={1,4,7},
    xticklabels/.expanded=\tiklist,
    ytick=\empty
    ]

    \addplot+[domain=0:10,samples=100,no markers]{sqrt(x)};

    \end{axis}

    \end{tikzpicture}

\end{document}
  • (+1) This should be the preffered way, all in TikZ syntax! – Guilherme Zanotelli Oct 13 '16 at 13:49
  • Agreed. While DC's answer will work in non-TikZ contexts, I understand what this one does, and it makes for much cleaner code. – JM114516 Oct 13 '16 at 15:01
8

You can force expansion via:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\usepackage{pgfplots} 


\begin{document}

    %The figure I want to obtain (but without giving "A1,A2,A3" explicitly)
    \begin{tikzpicture}
    \begin{axis}[
    xmin=0,xmax=10,
    ymin=0,ymax=4,
    xtick={1,4,7},
    xticklabels={A1,A2,A3},
    ytick=\empty
    ]

    \addplot+[domain=0:10,samples=100,no markers]{sqrt(x)};

    \end{axis}

    \end{tikzpicture}

    % This fails to do what I want, as the commas are not understood as value separators
    \begin{tikzpicture}
    \newcommand{\tiklist}{A1,A2,B}
    \edef\tmp{\noexpand\begin{axis}[
    xmin=0,xmax=10,
    ymin=0,ymax=4,
    xtick={1,4,7},
    xticklabels={\tiklist},
    ytick=\empty
    ]}\tmp

    \addplot+[domain=0:10,samples=100,no markers]{sqrt(x)};

    \end{axis}

    \end{tikzpicture}

\end{document}
  • What happened to \begin{picture}...\end{picture} ?? – Guilherme Zanotelli Oct 13 '16 at 9:50
  • Looks like dark magic to me, but hey, it works. Thanks! – JM114516 Oct 13 '16 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.