我目前正在试验 pgfplots 和 pgfplotstable 包。当我想知道是否可以使用类似电子表格的公式时,我注意到可以创建新列(复制或转换另一列)(这意味着新列的每个单元格的值应该是其左侧单元格(同一行)的值 + 上方单元格(同一列)的值,是的,必须进行一些初始化)。
有人知道这样的功能吗?如果知道,该怎么做?(无论它只是 pgfplotstable 还是 pgfplots)
答案1
pgfplotstable
这可以通过使用的\pgfplotstablecreatecol
宏(也可以使用 来create on use
延迟创建列数据,但从 返回后其内容将会丢失)的一些限制来实现\pgfplotstabletypeset
。根据pgfplotstable
文档:
目前,您一次只能访问一列的三个值:当前行、上一行和下一行。尚不支持访问任意索引。
在下面的例子中,我实现了问题中描述的公式,在“行 -1”中用(任意)值 100 对其进行初始化。由于初始表数据是:
x y
0 1
5 6
10 11
计算值为:
1 + 100 = 101
6 + 101 = 107
11 + 107 = 118
为了访问动态创建的列中先前计算的值,我将它们全局存储(这里:仅存储最近计算的值,使用\xdef\myPreviousValue{...}
),因为pgfplotstable
的\prevrow
宏似乎不允许访问正在创建的列中的值。如果访问任何需要在创建的列中预先计算的值,例如,可以使用pgfmath
数组1或或expl3
tl
变量。seq
\begin{filecontents*}{data.csv}
x y
0 1
5 6
10 11
\end{filecontents*}
\documentclass{article}
\usepackage{booktabs}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.16}
\pgfplotstableread[row sep=newline, col sep=space]{data.csv}\myTable
\newcommand*{\myPreviousValue}{100} % initialization (row -1, sort of)
% Dynamically create column z
\pgfplotstablecreatecol[
create col/assign/.code={%
\pgfmathsetmacro{\myValue}{int(\thisrow{y} + \myPreviousValue)}%
\pgfplotstableset{create col/next content/.expand once={\myValue}}%
\xdef\myPreviousValue{\myValue}%
}]
{z}\myTable
\begin{document}
\pgfplotstabletypeset[
columns/x/.style={column name={$x$}},
columns/y/.style={column name={$y$}},
columns/z/.style={column name={$z$}},
every head row/.style={before row=\toprule, after row=\midrule},
every last row/.style={after row=\bottomrule}
]{\myTable}
\end{document}
注意:我使用的表达式int()
中的pgfmath
可能看起来是不必要的,因为默认情况下,\pgfplotstabletypeset
使用 格式化值\pgfmathprintnumber
,并且同样默认情况下,\pgfmathprintnumber
检测输入的小数部分是否等于零,以便对整数的打印进行特殊处理。例如,\pgfmathprintnumber{118.0}
默认情况下打印 118。但是,如果没有int()
,存储在 — 中的值\myValue
以及创建的内存列和\myPreviousValue
— 中的值将带有尾随.0
;使用int()
函数可以防止这种情况。
脚注
- 搜索钛钾Z & PGF 手册对于“数组访问运算符”数学和面向对象引擎部分。