在我的源 CSV 文件中,每个数据系列有一列,因此我使用\foreach
迭代器遍历所有数据系列并将其添加到散点图中。我还想添加一个 TikZ 节点来标记并说明每列的平均值。
梅威瑟:
\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{
compat=1.18,
height=5cm,
width=5cm,
ymin=0,
}
\begin{document}
\begin{tikzpicture}
% load table
\pgfplotstableread{
typeA typeB typeC
9 14 5
10 14 3
11 14 7
9 14 6
9 14 4
11 13 5
11 15 8
}\loadedtable
% get number of rows
\pgfplotstablegetrowsof{\loadedtable}
\newcommand*{\loadedrows}{\pgfplotsretval}
% using pre-calculated number of rows
\newcommand{\average}[1]{%
\pgfkeys{/pgf/fpu}%
\pgfmathsetmacro\buffer{0.0}%
\pgfplotstableforeachcolumnelement{#1}\of\loadedtable\as\cellValue{%
\pgfmathsetmacro{\buffer}{\buffer + \cellValue}%
}%
\pgfmathsetmacro{\buffer}{\buffer / \loadedrows)}%
\pgfmathprintnumber{\buffer}%
}
% calculating number of rows on the fly
\newcommand{\averagetwo}[1]{%
\pgfkeys{/pgf/fpu}%
\pgfmathsetmacro\buffer{0.0}%
\pgfmathsetmacro\rows{0}%
\pgfplotstableforeachcolumnelement{#1}\of\loadedtable\as\cellValue{%
\pgfmathsetmacro{\buffer}{\buffer + \cellValue}%
\pgfmathsetmacro{\rows}{\pgfplotstablerow + 1}%
}%
\pgfmathsetmacro{\buffer}{\buffer / \rows)}%
\pgfmathprintnumber{\buffer}%
}
\node at (2, -1) {Type A avg: \average{typeA}};
\begin{axis}[
xtick={1,2,3},
xticklabels={A,B,C}
]
\foreach \type [count=\ctr] in {typeA,typeB,typeC} {%
\addplot [only marks, mark options={opacity=.3}]
table[x expr={\ctr}, y={\type}] {\loadedtable};
% (1)
%\node[fill=orange] at (\ctr, 1) {x};
% (2*)
%\edef\tmp{\noexpand\node[fill=orange] at (\ctr, 1) {\ctr};}
%\tmp
% (3)
%\edef\tmp{\noexpand\node[fill=orange] at (\ctr, 1) {\averagetwo{\type}};}
%\tmp
% (4)
%\edef\tmp{\noexpand\node[fill=orange] at (\ctr, \average{\type}) {x};}
%\tmp
% (5)
%\edef\tmp{\noexpand\node[fill=orange] at (\ctr, 1) {\noexpand\average{\type}};}
%\tmp
% (6*)
\edef\tmp{\noexpand\node[fill=orange] at (\ctr, 1) {\noexpand\averagetwo{\type}};}
\tmp
% (7)
%\edef\tmp{\noexpand\node[fill=orange] at (\ctr, \noexpand\averagetwo{\type}) {x};}
%\tmp
}
\end{axis}
\end{tikzpicture}
\end{document}
计算表列的平均值有两种实现方式,均基于https://tex.stackexchange.com/a/252360第一个函数用于\pgfplotstablegetrowsof
查找一次行数,第二个函数用于在每次调用时计算行数。
创建图表本身没有问题。但在星号上添加平均值的各种尝试中,都没有成功。
(1)
./mwe.tex:91: Undefined control sequence.
<argument> \ctr
, 1
l.91 \end{axis}
我推测这与某种程度上延迟执行代码的内部原因有关axis
,此时计数器不再可访问。
(2*)通过手动扩展计数器来解决这个问题,虽然可以工作,但还远远没有达到我的目标。
(3)+(4)导致无限循环。当我中断编译时,我得到
^C./mwe.tex:90: Interruption.
\pgfkeys@parse ...uturelet \pgfkeys@possiblerelax
\pgfkeys@parse@main
l.90 }
好的,但\average
不知何故这似乎是个问题。
(5)
./mwe.tex:91: Package PGF Math Error: Could not parse input '' as a floating po
int number, sorry. The unreadable part was near ''. (in '1Y7.0e1]/ )').
See the PGF Math package documentation for explanation.
Type H <return> for immediate help.
...
l.91 \end{axis}
由于某种原因\loadedrows
这里是空的。
在这种情况下,替代平均值计算有效(6*),但不会改变以前的错误。这是我最接近目标的一次。请注意,外面的 TikZ 节点axis
工作正常。
(7)导致与(3)和(4)相同的无限循环。
我的问题:
- 如何为每个数据系列添加一个节点,标记该系列的平均值并以文本形式包含平均值。最好这些节点应具有可从外部访问的名称
axis
。 \average
(6)为什么会失败?怎么会\loadedrows
突然为空?\average
我在里面直接使用会出现无限循环的原因是什么axis
?- (不是主要问题的直接部分,但相关:如何避免循环
{typeA,typeB,typeC}
中的列表\foreach
并直接从 CSV 中获取列名?