如果没有 axis 环境,我们可以这样写
\documentclass[beamer,crop]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\foreach \i in {1,2,3} {
\draw (rnd, rnd) -- (rnd, rnd) coordinate (name\i);
\node at (name\i) {name\i};
}
\end{tikzpicture}
\end{document}
坐标名称name\i
可以正确替换为name1
、name2
和name3
。但是在axis
环境中,它不起作用。以这个 MWE 为例:
\documentclass[beamer,crop]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\foreach \w in {1,2,...,3} {
\addplot[blue, mark=square, ycomb] coordinates {(\w, \w^2 - 1)}
coordinate (test\w);
}
\end{axis}
\end{tikzpicture}
\end{document}
它产生
未定义控制序列。test\w
答案1
正如 Qrrbrbirlbel 在评论中指出的那样,解决该问题的方法之一是扩展控制。以下是针对给定示例可能采取的方法:
\documentclass[beamer,crop]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\foreach \w in {1,2,...,3} {
\edef\z{coordinates {(\w, \w^2 - 1)} coordinate (test\w)}
\def\tmp{\addplot[blue, mark=square, ycomb]}
\expandafter\tmp\z;
}
\end{axis}
\end{tikzpicture}
\end{document}
这样,在循环的每一步中\addplot
都会提供 的扩展值。\w
答案2
另一个解决方案是
\documentclass[beamer,crop]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\pgfplotsinvokeforeach{1,2,3}{
\addplot[blue, mark=square, ycomb] coordinates {(#1, {#1^2 - 1})};
\edef\temp{\noexpand\coordinate (test#1) at (axis cs:#1,{#1^2 - 1});}
\temp
}
\end{axis}
Access the coordinates after the axis environment
\foreach \w in {1,2,3} {
\node at (test\w) {test\w};
}
\end{tikzpicture}
\end{document}
答案3
pgfplots
查找的手册\pgfplotsinvokeforeach
。
\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.18}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\pgfplotsinvokeforeach{1,2,...,3} {
\addplot[blue, mark=square, ycomb] coordinates {(#1, #1^2 - 1)}
coordinate (test#1);
}
\end{axis}
\end{tikzpicture}
\end{document}