当我尝试在箱线图中输出数据集的中值时\pgfplotsboxplotvalue{median}}
,计算出的值不是实际中值(见下文:2.5 而不是 3)。有办法解决这个问题吗?我不想在外部计算所有箱线图值(中位数、晶须……)。(我刚刚意识到箱子也未对齐。)
\documentclass{article}
\usepackage{filecontents}
\usepackage{pgfplots,pgfplotstable}
\usetikzlibrary{pgfplots.statistics}
\pgfplotsset{compat=1.16}
\begin{filecontents}{input.csv}
name,value
a,1
b,2
c,3
d,4
e,5
\end{filecontents}
\begin{document}
\begin{figure}
\begin{tikzpicture}
\pgfplotstableread[col sep=comma]{input.csv}\mydata
\pgfplotsset{
boxplot/draw/median/.code={
\draw [/pgfplots/boxplot/every median/.try]
(boxplot box cs:\pgfplotsboxplotvalue{median},0)
--
node[right, font=\tiny] {\pgfmathprintnumber{\pgfplotsboxplotvalue{median}}}
(boxplot box cs:\pgfplotsboxplotvalue{median},1);
},
}
\begin{axis}
\addplot+[boxplot] table[x=value] {\mydata};
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
答案1
恐怕这与准备好的箱线图和常用选项(请参阅版本 1.16 手册第 497 页pgfplots
)。这里,(1/2)⋅(x 2 + x 3 ) = (1/2)⋅(2 + 3) = 2.5。选择此表达式是因为 N = 5,因此当 p = 0.5 时,Np = 0.5⋅N 不是整数。
也就是说,假设您的数据已经排序,根据您选择的定义计算中位数并不是很困难:
\begin{filecontents}{input.csv}
name,value
a,1
b,2
c,3
d,4
e,5
\end{filecontents}
\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
\usetikzlibrary{pgfplots.statistics}
\pgfplotsset{compat=1.16}
\makeatletter
\newcommand*{\computeMedian}[3]{%
\pgfplotstablegetrowsof{#1}%
\let\@nbRows\pgfplotsretval
\ifodd\pgfplotsretval\relax
\pgfplotstablegetelem{\the\numexpr(\@nbRows-1)/2}{#2}\of{#1}%
\let#3\pgfplotsretval
\else
\pgfplotstablegetelem{\the\numexpr \@nbRows/2 - 1}{#2}\of{#1}%
\let\@firstValue\pgfplotsretval
\pgfplotstablegetelem{\the\numexpr \@nbRows/2}{#2}\of{#1}%
\let\@secondValue\pgfplotsretval
\pgfmathsetmacro{#3}{0.5*(\@firstValue + \@secondValue)}%
\fi
}
\pgfplotsset{
my median/.code 2 args={%
\computeMedian{#1}{#2}{\@tmp}%
\pgfkeyslet{/pgfplots/my median}{\@tmp}%
},
boxplot/draw/median/.code={
\draw [/pgfplots/boxplot/every median/.try]
(boxplot box cs:\pgfkeysvalueof{/pgfplots/my median},0)
--
node[right, font=\tiny]
{\pgfmathprintnumber{\pgfkeysvalueof{/pgfplots/my median}}}
(boxplot box cs:\pgfkeysvalueof{/pgfplots/my median},1);
},
}
\makeatother
\pgfplotstableread[col sep=comma]{input.csv}\mydata
\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot+[boxplot, my median={\mydata}{value}] table[x=value] {\mydata};
\end{axis}
\end{tikzpicture}
\end{document}
和:
\begin{filecontents}[overwrite]{input.csv}
name,value
a,1
b,2
c,3
d,4
e,5
f,6
\end{filecontents}
你会得到:
如果您的数据尚未排序,您可以根据现有的数据创建一个新表,并根据您选择的列进行排序,方法如下:
\pgfplotstablesort[sort key={column}]\resulttable\sourcetable
然后您可以将前面的方法应用于\resulttable
。另一个选项是将所有值转储到expl3
seq
变量并使用\seq_sort:Nn
。