我希望能够使用宏来指定列表(它是一个常量列表,即在整个文档中不会改变),并使用这个宏而不是在 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
。