犹豫着要不要再问一个令人尴尬的问题,但我似乎看不出\foreach
MWE 中的问题。它应该产生几条水平线,但只产生了一条带有 的水平线,yValue
如 中指定的那样\newcommand{\yValue}{0.3}
:
代码:
\documentclass{article}
\usepackage{pgfplots}
\newcommand{\yValue}{0.3}
\begin{document}
\begin{tikzpicture}
\begin{axis}
[
ymin=0,
ymax=1,
xmin=0,
xmax=1,
]
\foreach \yValue in {0.00,0.1,...,1.00} {
\draw [red] (axis cs:0,\yValue) -- (axis cs:1,\yValue);
}
\end{axis}
\end{tikzpicture}
\end{document}
答案1
根据第 470-471 页pgfplots
文档:
(笔记:在pgfplots
文档 v1.17 中,页码范围已更改为 544-545。
请记住,在轴环境中,所有循环构造(包括自定义循环
\foreach
和\pgfplotsforeachungrouped
)都需要小心处理:循环参数只能在立即求值的地方使用;但pgfplots
会推迟许多宏的求值。例如,要循环某些东西并生成形式为的轴描述\node at (axis cs:\i,0.5)....
,循环宏\i
将在中求值\end{axis}
——但此时,循环结束并且其值丢失。处理此类应用程序的正确方法是扩张循环变量明确地。
因此,您需要执行以下操作:
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}
[
ymin=0,
ymax=1,
xmin=0,
xmax=1,
]
\foreach \yValue in {0.00,0.1,...,1.00} {
\edef\temp{\noexpand\draw [red] (axis cs:0,\yValue) -- (axis cs:1,\yValue);}
\temp
}
\end{axis}
\end{tikzpicture}
\end{document}
编辑
作为@percusee 在评论中指出,你也可以使用\pgfplotsinvokeforeach
。这与 不同\foreach
,因为根据第 471 页文档:
不会
\x
被扩大,而#1
是。
也就是说,它确实完成了需要做的事情,以处理pgfplots
直到才评估循环宏的事实\end{axis}
。
因此,您还可以执行以下操作:
\pgfplotsinvokeforeach{0.00,0.1,...,1.00}{
\draw [red] (axis cs:0,#1) -- (axis cs:1,#1);
}
请注意,语法略有不同。\pgfplotsinvokeforeach
使用#1
,就像\newcommand
会一样,而不是允许您命名自己的变量。
答案2
我遇到了类似的问题,上面的答案对我没有用。然而,我意识到你经常想使用foreach
里面环境axis
,因为您想要访问axis cs
坐标系。我想出了以下解决方法,我在此展示了原始 MWE 的解决方法:
\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\begin{axis}[ymin=0, ymax=1, xmin=0, xmax=1]
\coordinate (O) at (axis cs:0,0);
\coordinate (X) at (axis cs:1,0);
\coordinate (Y) at (axis cs:0,1);
\end{axis}
\begin{scope}[x={($(X)-(O)$)}, y={($(Y)-(O)$)}, shift={(O)}]
\foreach \y in {0, 0.1, ..., 1} {
\draw[red] (0,\y) -- (1,\y);
}
\end{scope}
\end{tikzpicture}
\end{document}
scope
这个想法显然是您在离开环境后“重新创建”坐标系axis
。这也适用于 3D 坐标。(请注意,在较新版本中,pgfplots
您不再需要前缀axis cs:
。)