这个问题基本上是这个答案. 假设我的输入表如下所示,我该如何处理 PGF 箱线图中的异常数据:
\pgfplotstableread{
index lw lq med uq uw out1 out2 out3
0 5 7 8.5 9.5 10 4 11 12
1 4 5 6.5 8.5 9.5 3 2 13
}\datatable
完整的 MWE 如下所示:
\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\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
\usepackage{filecontents}
\pgfplotstableread{
index lw lq med uq uw out1 out2 out3
0 5 7 8.5 9.5 10 4 11 12
1 4 5 6.5 8.5 9.5 3 2 13
}\datatable
\begin{document}
\begin{tikzpicture}
\begin{axis}[boxplot/draw direction=y]
\pgfplotstablegetrowsof{\datatable}
\pgfmathtruncatemacro\TotalRows{\pgfplotsretval-1}
\pgfplotsinvokeforeach{0,...,\TotalRows}
{
% select outlier data
\pgfplotstablegetelem{#1}{out1}\of\datatable
\let\oA=\pgfplotsretval
\pgfplotstablegetelem{#1}{out2}\of\datatable
\let\oB=\pgfplotsretval
\pgfplotstablegetelem{#1}{out3}\of\datatable
\let\oC=\pgfplotsretval
\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
]
table[row sep=\\]{\oA \\ \oB\\ \oC}; % here is the problem
% add legend entry
\pgfplotstablegetelem{#1}{index}\of\datatable
\addlegendentryexpanded{\pgfplotsretval}
}
\end{axis}
\end{tikzpicture}
\end{document}
如果这有助于获得更方便的解决方案,那么它也将是重组我的输入表的选项。
答案1
由于扩展问题,您不能简单地从宏中读取表格。相反,我建议您查看宏\pgfplotstabletranspose
,它在这里可能非常有用。您可以通过选项指定在转置之前应选择的列columns
。
我认为,您想要获得的是以下内容(感谢您指出有关列的选择的问题!):
\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\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{
index lw lq med uq uw out1 out2 out3
0 5 7 8.5 9.5 10 4 11 12
1 4 5 6.5 8.5 9.5 3 2 13
}\datatable
\pgfplotstabletranspose[columns={out1, out2, out3}]
\datatableoutliers{\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
]
table [y=#1] {\datatableoutliers};
% add legend entry
\pgfplotstablegetelem{#1}{index}\of\datatable
\addlegendentryexpanded{\pgfplotsretval}
}
\end{axis}
\end{tikzpicture}
\end{document}