在 TikZ/PGFplots 中使用宏定义列表

在 TikZ/PGFplots 中使用宏定义列表

我希望能够使用宏来指定列表(它是一个常量列表,即在整个文档中不会改变),并使用这个宏而不是在 TikZ/PGFplots 中对列表内容进行硬编码以提高可读性。这个问题在之前关于foreach循环的问题,但这不是该问题的主要内容。

以下是相关问题如何保持与 TikZ 和 pgfplots 的一致性,以及它的延续在 pgfplots 中使用宏作为坐标,但这些与指定坐标有关,而不是列表。

在下面的 MWE 中,示例 1 的解决方案基于关于在 foreach 中使用宏定义列表的这个问题建议不要将宏定义列表括在花括号中。这对于 TikZ 来说很有效,所以目前没有问题。

然而,在 PGFplots 中情况有所不同。示例 2 中的解决方案foreach来自上述问题,并且只要我这样做,效果就很好不是对列表使用宏,但我更喜欢在这里使用宏。

在示例 3 中,我可以轻松地使用宏定义列表xtick,但不是能够用它做xticklabels

那么,有没有一种一致的方法,让我可以始终为列表定义宏,然后使用它而不必担心其使用上下文?如果没有,有没有办法改变列表的定义和/或其在示例 2 和 3 中的用法,使其在这些情况下有效。

\documentclass{article}
\usepackage{pgfplots}

\newcommand*{\XTickLocationList}{-2, -1, 1, 2}
\newcommand*{\XTickLabelsList}{a, b, c, d}
\newcommand*{\XTickLocationsAndLabels}{-2/a, -1/b, 1/c, 2/d}

\begin{document}
\begin{tikzpicture}   % Example 1
\draw [->][gray, thin](-3,0) -- (3,0) node[blue, right] {$x$}; 
\draw [->][gray, thin](0,-3) -- (0,3) node[blue, above] {$y$};

%\foreach \x/\l in {-2/a, -1/b, 1/c, 2/d} { % Works
%\foreach \x/\l in {\XTickLocationsAndLabels} {  % Does not compile
\foreach \x/\l in \XTickLocationsAndLabels {  % Works
    \draw [thick, red]
        (\x,-2pt) -- (\x,2pt)
        node [red, above] {\l};
}
\end{tikzpicture}

\begin{tikzpicture}   % Example 2
\begin{axis}[
    minor tick num=0, 
    axis y line=center, 
    axis x line=middle, 
    xmin=-3, xmax=3, 
    ymin=-3, ymax=3,
    xlabel=$x$, ylabel=$y$,
    xtick={0},  xticklabels={}
    ]

\foreach \x/\l in {-2/a, -1/b, 1/c, 2/d}{ % Works
%\foreach \x/\l {\XTickLocationsAndLabels}  % Does not compile
%\foreach \x/\l \XTickLocationsAndLabels  % Does not compile
    \edef\temp{\noexpand\addplot
        [mark=none,color=red, thin, samples=2]%
        coordinates{ (\x,-0.05) (\x,0.05) }
            node [red, below] {\l};
    }
    \temp
} 

\end{axis}
\end{tikzpicture}

\begin{tikzpicture}    % Example 3
\begin{axis}[
    minor tick num=0, 
    axis y line=center, 
    axis x line=middle, 
    xmin=-3, xmax=3, 
    ymin=-3, ymax=3,
    xlabel=$x$, ylabel=$y$,
    %xtick={-2, -1, 1, 2}, % Works
    %xtick=\XTickLocationList, % Works
    xtick={\XTickLocationList}, % Works
    xticklabels={a, b, c, d}  % Works
    %xticklabels={\XTickLabelsList}  % Compiles, but wrong results
    %xticklabels=\XTickLabelsList  % Compiles, but wrong results
    ]

\end{axis}
\end{tikzpicture}
\end{document}

答案1

鉴于我在上面的评论中讨论的限制,我建议使用更技术性的方法 - 绝对可靠且完全可移植(但在 LaTeX 中不太常见)。

我的意思是,问题是 pgfplots 不理解xticklabels={\XTickLabelsList}。更准确地说:它将参数作为(单个)列表条目而不是扩展它。说实话,我甚至不确定是否有人可能使用这样的功能(以宏为内容的单元素列表)。

因此,我们需要提供内容\XtickLabelsList编程方式。

好吧,这是承诺的解决方案:


\edef\temp{%
  \noexpand\pgfplotsset{%
      x tick labels list/.style={xticklabels={\XTickLabelsList}}
  }%
}
\temp
它定义\temp为在括号中包含参数的“完全展开”内容(“展开的”定义)。如果\noexpand的参数中出现\edef,则后面项的“完全展开”内容\noexpand是项本身,即\noexpand\pgfplotsset保持不变\pgfplotsset。但\XTickLabelsList将被其内容替换。请注意, 中可能出现的任何宏\XTicjLabelsList也可能被展开(还有其他技术可以避免这种情况。如果您需要它们,请再次提出问题或在我的 TeX-programming-notes.pdf 中进行研究,该文档应随 pgfplots 一起提供)。

无论如何,\temp宏最终将包含\pgfplotsset{.....{a,b,c,d}}}(键入\show\temp以验证它)。执行\temp将激活更改,之后您可以轻松使用该样式x tick labels list

相关内容