pgfplots 中的标量场

pgfplots 中的标量场

我想制作一个 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>}

在此材料中,你可以使用\foreachTikZ 中的方法 - 无需所有这些\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 编程的详细信息。

相关内容