我想创建 tikzpicture(实际上是动画),它可以从文本文件中读取数字,并将它们用作坐标或节点或用于进一步计算。似乎 datatool 包是合适的,但我只能在直接传递参数时才能使其工作,就像在 MWE 中一样:
\documentclass{standalone}
\usepackage{filecontents}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{datatool}
\usepackage{animate}
\begin{filecontents*}{test.csv}
f wzb em
380 5 3
400 1 2
405 2 5
410 43 5656
415 4 94
420 4 6
\end{filecontents*}
\DTLsetseparator{ }
\DTLloaddb{widmo}{test.csv}
\begin{document}
\begin{animateinline}[label=graph_switch,controls=step]{1}
\multiframe{5}{iFrame=400+5}{
\begin{tikzpicture}
\useasboundingbox[draw] (-3,-2) rectangle (5,6);
\pgfmathparse{1000/\iFrame}
\edef\dlugosc{\pgfmathresult}
\DTLassignfirstmatch{widmo}{f}{405}{\wzb=wzb,\em=em}
%\DTLassignfirstmatch{widmo}{f}{\dlugosc}{\wzb=wzb,\em=em}
%\DTLassignfirstmatch{widmo}{f}{\iFrame}{\wzb=wzb,\em=em}
\draw[->] (0,0) -- (\wzb, \em) --(\dlugosc:1) node[left] {\dlugosc};
\node at (2,0) {em=\em, wzb=\wzb};
\end{tikzpicture}
}
\end{animateinline}
\end{document}
注释掉的两行不像我想象的那样工作。有没有简单的方法可以修复它,或者有其他包可以让我浏览文本文件,从特定行中选取值并将其用作变量?如果对此有任何建议,我将不胜感激。
答案1
一般来说,当你遇到如下宏调用时
\DTLassignfirstmatch{widmo}{f}{\iFrame}{\wzb=wzb,\em=em}
其中宏似乎需要实际数据,而不是\iFrame
引用数据,您需要扩展保存数据的命令,在这种情况下\iFrame
。
如果您很幸运,\iFrame
将包含数据的实际标记,并且只需要一次扩展即可获得它们。如果您不走运,宏\iFrame
将根本无法扩展,在这种情况下,我所描述的方法将无法解决您的问题。在这两个极端之间,\iFrame
可能需要有限次数的扩展才能产生所需的数据标记(我不会在这里描述如何实现这一点,但有方法可以做到这一点)。
幸运的是,在我们的例子中,\iFrame
包含实际的数据标记,因此只需要进行一次扩展。实现此目的的典型方法如下
\def\tmp{\DTLassignfirstmatch{widmo}{f}}
\expandafter\tmp\expandafter{\iFrame}{\wzb=wzb,\em=em}
在这里,我们将括号平衡表达式存储在\iFrame
临时宏中\tmp
。然后,可以使用\expandafter
来扩展\iFrame
前正在扩展\tmp
。因此,在执行时\DTLassignfirstmatch
,的出现\iFrame
已经扩展为\DTL...
宏所需的实际数据标记。
答案2
的文档datatool
对此有明确的说明:
\DTLassignfirstmatch{⟨db name⟩}{⟨col key⟩}{⟨value⟩}{⟨assign list⟩}
这与以下类似,
\DTLassign
不同之处在于它适用于给定数据库中的第一行,其中标签标识的列⟨col key⟩
具有给定值的第一行。请注意,匹配中没有进行任何扩展。该值必须完全匹配。
(第 98 页,重点已添加。)
另一方面,紧接着这个描述你会发现
\xDTLassignfirstmatch{⟨db name⟩}{⟨col key⟩}{⟨value⟩}{⟨assign list⟩}
这类似于
\DTLassignfirstmatch
,但对执行了一级扩展⟨value⟩
。
所以你想使用
\xDTLassignfirstmatch{widmo}{f}{\iFrame}{\wzb=wzb,\em=em}
但是,如果我尝试,我会得到“尺寸太大”的结果。
无论如何,如果我用
\def\iFrame{405}
\xDTLassignfirstmatch{widmo}{f}{\iFrame}{\wzb=wzb,\em=em}
\verb|\wzb| = \wzb
\verb|\em| = \em
我明白了