箱线图中的中位数计算

箱线图中的中位数计算

当我尝试在箱线图中输出数据集的中值时\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

相关内容