我的问题有点涉及此主题。我想从文件创建箱线图。文件(在我的情况下是 CSV)如下所示:
Upper,Lower,Min,Max,Median,Name
3,1,0,4,2,First
4,2,1,5,3,Second
...
有多个行,每行包含描述箱线图的数据点(中位数、晶须位置和箱线边界)和数据集名称的字段。我想根据这些数据创建多个箱线图。名称应添加为图例条目。
我曾尝试使用 CSV 阅读器:
\begin{tikzpicture}
\begin{axis}[
\csvreader[
head to column names,
separator=comma]
{data.csv}{}% use head of csv as column names
{
\addplot+ [
boxplot prepared={
lower whisker=\Min,
lower quartile=\Lower,
median=\Median,
upper quartile=\Upper,
upper whisker=\Max,
},
] coordinates {};
}
\end{axis}
\end{tikzpicture}
但这会产生一个空图。我猜想宏(\Min
等等)在tikzpicture
/axis
环境中无法正常工作?!(当我将图片外的值转储出来时,它可以正常工作)。
我也看了上面提到的话题。本例中的问题是,只绘制了表格的第一行,而我想绘制全部评论中提到了这个缺点,但没有提到该方法的扩展。
添加图的最佳方法是什么?
答案1
你可以将 Jake 的回答延伸到从表中读取箱线图准备好的值相当容易,使用\pgfplotsinvokeforeach
。
下面的代码基于 Jake 的回答,只做了一些修改:
从表中获取行数的方法:
\pgfplotstablegetrowsof{\datatable} \pgfmathtruncatemacro\TotalRows{\pgfplotsretval-1}
减一,因为行/列号在索引中从 0 开始计数。
一个循环而不是两个不同的
\addplot
:\pgfplotsinvokeforeach{0,...,\TotalRows}{ \addplot .. }
row=#1
注意在箱线图选项中添加了,在\pgfplotsinvokeforeach
循环中变量用表示#1
。添加
area legend
到\addplot
选项中,否则图例图像就是完整的(大)箱线图。从表中添加图例条目:
\pgfplotstablegetelem{#1}{name}\of\datatable \addlegendentryexpanded{\pgfplotsretval}
\documentclass[crop=false]{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.8}
\usepgfplotslibrary{statistics}
\makeatletter
\pgfplotsset{
boxplot prepared from table/.code={
\def\tikz@plot@handler{\pgfplotsplothandlerboxplotprepared}%
\pgfplotsset{
/pgfplots/boxplot prepared from table/.cd,
#1,
}
},
/pgfplots/boxplot prepared from table/.cd,
table/.code={\pgfplotstablecopy{#1}\to\boxplot@datatable},
row/.initial=0,
make style readable from table/.style={
#1/.code={
\pgfplotstablegetelem{\pgfkeysvalueof{/pgfplots/boxplot prepared from table/row}}{##1}\of\boxplot@datatable
\pgfplotsset{boxplot/#1/.expand once={\pgfplotsretval}}
}
},
make style readable from table=lower whisker,
make style readable from table=upper whisker,
make style readable from table=lower quartile,
make style readable from table=upper quartile,
make style readable from table=median,
make style readable from table=lower notch,
make style readable from table=upper notch
}
\makeatother
\pgfplotstableread{
lw lq med uq uw name
5 7 8.5 9.5 10 first
4 5 6.5 8.5 9.5 second
}\datatable
\begin{document}
\begin{tikzpicture}
\begin{axis}[boxplot/draw direction=y]
\pgfplotstablegetrowsof{\datatable}
\pgfmathtruncatemacro\TotalRows{\pgfplotsretval-1}
\pgfplotsinvokeforeach{0,...,\TotalRows}
{
\addplot+[
boxplot prepared from table={
table=\datatable,
row=#1,
lower whisker=lw,
upper whisker=uw,
lower quartile=lq,
upper quartile=uq,
median=med
},
boxplot prepared,
% to get a more useful legend
area legend
]
coordinates {};
% add legend entry
\pgfplotstablegetelem{#1}{name}\of\datatable
\addlegendentryexpanded{\pgfplotsretval}
}
\end{axis}
\end{tikzpicture}
\end{document}