我认为我需要一种方法来刷新 PGF 命令,因为引用\LabelText
使用最后一个值,而不是调用时的值。该宏旨LabelPoint
在替换所示的第一个\addplot
命令,并使用坐标或指定的标签(如果给出)标记该点。但是,两个点都被标记为top
。
\documentclass{article}
\usepackage{pgfplots}
\usepackage{xparse}
\begin{document}
\newcommand{\LabelText}{}
\NewDocumentCommand{\LabelPoint}{o o m m g}{
\IfNoValueTF{#5}{
\renewcommand{\LabelText}{$(#3,#4)$} % Label with given coordinates
}{
\renewcommand{\LabelText}{#5} % Use given label
}
\addplot [#1] coordinates{(#3,#4)} node [#2] {\LabelText};
%\pgfsyssoftpath@flushcurrentpath % -- Syntax error
%\pgfusepath{fill} % -- no effect
}
\NewDocumentCommand{\LabelPointX}{o o m m g}{
\IfNoValueTF{#5}{
\addplot [#1] coordinates{(#3,#4)} node [#2] {$(#3,#4)$};
}{
\addplot [#1] coordinates{(#3,#4)} node [#2] {#5};
}
}
\begin{tikzpicture}
\begin{axis}
\addplot [mark=*,color=red] coordinates{(0,0)} node [color=blue, below] {$(0,0)$};
\LabelPoint[mark=*,color=red][color=blue, below]{0.5}{0.5}{middle}
\LabelPoint[mark=*,color=red][color=blue, below]{1 }{1 }{top}
\end{axis}
\end{tikzpicture}
\end{document}
我认为问题与 PGF 命令未被刷新有关,但我似乎无法让它工作——我已注释掉我尝试过的内容。
我也不喜欢拥有全局变量\LabelText
,因为它只在宏范围内才有意义,所以任何将其移动到范围内的帮助\NewDocumentCommand
也会有所帮助。
\LabelTextX
使用两个不同命令的修改版本\addplot
可以工作,但这只会使代码更难阅读,并且在涉及更多条件时变得复杂,所以我真的不想使用它作为解决方案。
答案1
如果我理解正确的话,\LabelPointX
它会按照你的要求执行,并\LabelPoint
执行相同的操作。你想要重构,\LabelPoint
这样重复性就会降低。
您喜欢这个实现吗?
\NewDocumentCommand{\LabelPointY}{o o m m g}{
\addplot [#1] coordinates{(#3,#4)} node [#2] {\IfNoValueTF{#5}{$(#3,#4)$}{#5}};
}
这不需要任何临时变量,也不会重复任何内容。
答案2
这是一个扩展问题。标签文本按原样传递给路径生成器,并在不扩展的情况下存储。它仅在构建路径时扩展,由于您在单个路径上执行了几次此操作,因此标签文本都扩展为相同的内容。您可以通过将宏的内容括\LabelPoint
在 TeX 分组级别中(例如,通过将左括号和右括号加倍)来看到这种情况。这会导致更改\LabelText
仅限于定义,并且在构建路径时,它使用全局版本(恰好为空)。
因此,解决方案是以预扩展的方式将标签文本宏传递给路径。如果推广,这可能会有点问题,而且有很多解决方案。至于哪个最好,我没有资格评判!这里有一种方法,它使用辅助宏和单个\expandafter
。
\documentclass{article}
\usepackage{pgfplots}
\usepackage{xparse}
\begin{document}
\newcommand{\LabelText}{}
\NewDocumentCommand{\LabelPoint}{o o m m g}{
\def\plotcmd{\addplot [#1] coordinates{(#3,#4)} node [#2]}
\IfNoValueTF{#5}{
\renewcommand{\LabelText}{ {$(#3,#4)$}} % Label with given coordinates
}{
\renewcommand{\LabelText}{ {#5}} % Use given label
}
\expandafter\plotcmd\LabelText;
%\pgfsyssoftpath@flushcurrentpath % -- Syntax error
%\pgfusepath{fill} % -- no effect
}
\NewDocumentCommand{\LabelPointX}{o o m m g}{
\IfNoValueTF{#5}{
\addplot [#1] coordinates{(#3,#4)} node [#2] {$(#3,#4)$};
}{
\addplot [#1] coordinates{(#3,#4)} node [#2] {#5};
}
}
\begin{tikzpicture}
\begin{axis}
\addplot [mark=*,color=red] coordinates{(0,0)} node [color=blue, below] {$(0,0)$};
\LabelPoint[mark=*,color=red][color=blue, below]{0.5}{0.5}{middle}
\LabelPoint[mark=*,color=red][color=blue, below]{1 }{1 }{top}
\end{axis}
\end{tikzpicture}
\end{document}
请注意,我们在宏中加入了括号\LabelText
。这只会让组装最终命令变得更容易一些。使用辅助\plotcmd
宏只会节省很多s \expandafter
。整个目的是\LabelText
应该在命令处理之前进行扩展\addplot
,以便价值看到的是of \LabelText
,而不是\LabelText
它本身。因此,TeX 愉快地解析了这一行,看到了,\expandafter
所以\LabelText
首先扩展。然后跳回扩展\plotcmd
,扩展到\addplot ...
内容。然后它再次从开始,\addplot
但现在,由于我们的扩展魔法,输入流由以下部分组成:
\addplot [#1] coordinates {(#3,#4)} node [#2] {label};
这正是我们想要的: