我想制作一个 PGF 图,除了普通的二维图之外,还包括标量场,即二维图各个位置的二维函数值。
当然,我尝试使用\foreach
命令来做到这一点。首先,我从 stackexchange 了解到,运行循环需要使用 进行一些额外的调整\edef
。但我仍然不知道如何实际计算两个参数的函数。 \pgfmathparse
根本行不通。下面的示例没有求和\i
,\j
而是简单地将它们一个挨着一个地写下来。
也许我的想法完全错误,还有更简单的方法来绘制标量场。有人能帮我吗?
问候,马可。
\documentclass{minimal}
\usepackage{tikz,pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[domain=-2.5:2.5,view={0}{90},axis background/.style={fill=white},]
\addplot {x^2};
\foreach \i in {-2.4,-1.2,...,2.4}
{\foreach \j in {-2.4,-1.2,...,2.4}
{\edef\temp{\noexpand \node at (axis cs:\i,\j) {\pgfmathparse{\i+\j}\pgfmathresult};}
\temp}}
\end{axis}
\end{tikzpicture}
\end{document}
答案1
这是一个扩展问题。
话虽如此,我可以向您介绍 TeX 的扩展控制——这就是您在这里所做的。
在写这篇文章时,我脑子里还有另外两个问题:第一个是问自己,这一切背后是否有某种功能要求。也许轴内编程循环的整个处理需要由专家(即我作为 pgfplots 的作者)仔细考虑。显然,轴的特殊要求会造成混乱(而您并不是第一个遭受这种困扰的人)。
第二个问题是:您是否有兴趣学习 TeX 以便能够编写脚本?循环是“脚本”。不幸的是,正如您已经知道的那样,需要在轴内进行特殊处理。如果是这样,我下面的回答可能就足够了。
如果您对这种脚本并不真正感兴趣(并且您只是为了解决手头的这个基本问题而这样做),那么我可能会指出该nodes near coords
功能,结合和\addplot3 table
/或\addplot3 {<expression>}
可能会做您需要的事情 - 无需借助脚本,只需借助高级方法。
我现在重新来回答你的问题:
解决方案 1
由于您的循环实际上只添加了注释而没有添加图表,因此您可以将完整的处理推迟到可视化阶段。
\draw
如果您在轴内写入或,就会发生这种情况\node
:pgfplots 会自动收集到下一个分号为止的(未展开的)参数;
,并将执行推迟到可视化阶段。
构建\edef
对于混合轴的可视化阶段和调查阶段是必要的(调查==涉及需要更新限制的图等)。
Pgfplots 提供了一种简单的方法来将事情推迟到可视化阶段:
\pgfplotsextra{<material which is postponed to the visualization phase>}
。
在此材料中,你可以使用\foreach
TikZ 中的方法 - 无需所有这些\edef
、\noexpand
等等:
\pgfplotsextra{
\foreach \i in {-2.4,-1.2,...,2.4}
{\foreach \j in {-2.4,-1.2,...,2.4}
{\node at (axis cs:\i,\j) {\pgfmathparse{\i+\j}\pgfmathprintnumber{\pgfmathresult}};}
}
}
请注意我\pgfmathprintnumber
在这里添加了。
解决方案 2
要修复您的文本,获取当前问题的答案,并了解有关 TeX 脚本的知识,请按以下步骤操作:
\noexpand
解决方法是在前面添加全部你的构造中的宏\edef
——除非你明确地知道应该立即扩大价值。
正确的解决方案是
\foreach \i in {-2.4,-1.2,...,2.4}
{\foreach \j in {-2.4,-1.2,...,2.4}
{\edef\temp{\noexpand \node at (axis cs:\i,\j) {\noexpand\pgfmathparse{\i+\j}\noexpand\pgfmathresult};}
\temp}}
解释如下:
\edef
表示“扩展定义”。它定义\temp
为包含后续所有内容的完整扩展 - 其中“完整扩展”表示扩展所有内容,直到无法进一步扩展为止。在 TeX 中,存在“可扩展”和“不可扩展”材料之间的区别。学会区分哪种材料是可扩展的似乎很困难而且技术性很强 - 但有一个非常简单的启发式方法在 99% 的情况下都是正确的:如果某物是“可执行的”,那么你可以肯定它不能被扩展。如果某物“仅包含一个值”,那么你几乎肯定可以扩展它。
这里\node
,\pgfmathparse
都是可执行的。因此,它们不能扩展 - 并且需要保护以防止扩展。忽略保护将导致无法预料和不可预测的结果(如您的情况)。
相反,\i
和\j
是单一值 - 并且可以扩展(这是这里的整个想法)。
\edef
可以通过在相关宏前面加上前缀来“保护某些内容不被扩展”\noexpand
。
这解释了\noexpand\node
和\noexpand\pgfmathparse
。
\noexpand\pgfmathresult
最后,您还必须添加-- 因为\pgfmathresult
应该是您的 的结果\pgfmathparse
,而不是 的当前值\pgfmathresult
。
啊 - 您可能需要考虑\noexpand\pgfmathprintnumber{\noexpand\pgfmathresult}
在这里使用解决方案 1。
也可以看看http://pgfplots.sourceforge.net/TeX-programming-notes.pdf有关 TeX 编程的详细信息。