根据表格准备的箱线图,使用行名而不是​​数字进行访问

根据表格准备的箱线图,使用行名而不是​​数字进行访问

我有 csv 文件1,我想将其绘制为箱线图。我找到了该部分问题的解决方案这里(由杰克提供),这构成了我的 MWE 的很大一部分。

这里的区别是我希望能够从一行中生成每个箱线图姓名而不是数字。这是我的 MWE:

\documentclass{article}

\usepackage{pgfplotstable}

\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,
                make style readable from table=average
}
\makeatother

\newcommand{\computerowindex}[2]{
\def\xindex{-1}
\pgfplotstableforeachcolumnelement{x}\of#1\as\cell{%
\edef\cellname{#2}
    \ifx\cell\cellname\let\xindex\pgfplotstablerow\fi   
}
}
\newcommand{\boxplotprepared}[2]{
\computerowindex{#1}{#2}
\expandafter\boxplotpreparedNum\expandafter#1\xindex
}

\newcommand{\boxplotpreparedNum}[2]{

\addplot[boxplot prepared from table={
    table=#1,
    row=#2,
    average=mean,
    lower whisker = min,
    upper whisker = max,
    lower quartile = fq,
    upper quartile = tq,
    median=median},
    boxplot prepared]
coordinates {};
%
}

\begin{document}

\pgfplotstableread{
x   min qu2 fq  median  tq  max mean
a1  19.9    21.384  25.175  28.05   31.425  44.6    28.366
a2  22.4    24  26.975  29.4    31.65   45.6    29.509
a3  29.1    29.398  32.1    34.9    38.175  48.9    35.582
b1  33.5    34.494  41.3    46.15   54.725  108.1   49.749
b2  39.2    41.662  52.625  64.1    83.3    126.3   69.364
b3  42.7    45.092  66.2    80.05   102.8   213.2   88.251
c1  54.4    56.76   75.5    107.9   135.45  195.7   109.501
c2  54.7    59  96.8    123.45  152.725 331.2   132.139
c3  64.7    65.99   102.95  139 200.025 348.2   153.915
d1  74.4    86.818  136.9   176.25  221.925 503.4   189.913
d2  80.6    100.508 144.175 191.7   247.5   454.1   205.501
d3  73.3    110.804 174.15  227.5   294.7   632.3   247.584
e1  98.2    111.55  163.1   222.15  300.05  512.4   240.966
e2  110.9   112.768 181.125 236.4   325.975 719.3   266.793
}{\loadedtable}

\begin{tikzpicture}
\begin{axis}[
             boxplot/draw direction=y,
             boxplot/average={auto},
             boxplot/every average/.style={/tikz/mark=*,mark size=1},
             ymin=0,ymax=800]
\boxplotprepared{\loadedtable}{a1}
\boxplotprepared{\loadedtable}{a2}
\boxplotprepared{\loadedtable}{a3}
\boxplotprepared{\loadedtable}{b1}
\boxplotprepared{\loadedtable}{b2}
\boxplotprepared{\loadedtable}{b3}
\boxplotprepared{\loadedtable}{c1}
\boxplotprepared{\loadedtable}{c2}
\boxplotprepared{\loadedtable}{c3}
\boxplotprepared{\loadedtable}{d1}
\boxplotprepared{\loadedtable}{d2}
\boxplotprepared{\loadedtable}{d3}
\boxplotprepared{\loadedtable}{e1}
\end{axis}
\end{tikzpicture}

\end{document}

在此处输入图片描述

对于小于 10 的行数,此方法可以正常工作,但一旦达到两位数,它就会截断数字并使用第 1 行,而不是 10、11、12 等。问题就在这里

\newcommand{\boxplotprepared}[2]{
\computerowindex{#1}{#2}
\expandafter\boxplotpreparedNum\expandafter#1\xindex
}

如果我理解正确,\expandafter会导致首先\xinput评估数字12(例如),因此\boxplotpreparedNum1其作为第二个参数,而第二个数字会丢失,因为它在环境中浮动axis。不过这些\expandafter命令似乎是必要的。如果我删除其中任何一个,就会出现错误,如果我同时删除两个,就会出现无意义的输出。我认为使用\let\edef定义\xinput会使它们变得不必要,但我不知道为什么它们不会。

如果有一种方法可以在命令中使用括号括住参数\expandafter,那将是最简单的解决方案,但我尝试过的任何组合都不起作用,所以我甚至不确定是否可行。

我怎样才能让它工作?

1. 请注意,我已经在 MWE 代码中直接定义了该表;据我所知,它与当前问题无关。

答案1

事实证明,我对括号的思考是正确的。我没有意识到这是{一个标记,因此添加括号需要额外的一个\expandafter

\newcommand{\boxplotprepared}[2]{
\computerowindex{#1}{#2}
\expandafter\boxplotpreparedNum\expandafter#1\expandafter{\xindex}
}

在此处输入图片描述

完整 MWE:

\documentclass{article}

\usepackage{pgfplotstable}

\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,
                make style readable from table=average
}
\makeatother

\newcommand{\computerowindex}[2]{
\def\xindex{-1}
\pgfplotstableforeachcolumnelement{x}\of#1\as\cell{%
\edef\cellname{#2}
    \ifx\cell\cellname\let\xindex\pgfplotstablerow\fi   
}
}
\newcommand{\boxplotprepared}[2]{
\computerowindex{#1}{#2}
\expandafter\boxplotpreparedNum\expandafter#1\expandafter{\xindex}
}

\newcommand{\boxplotpreparedNum}[2]{

\addplot[boxplot prepared from table={
    table=#1,
    row=#2,
    average=mean,
    lower whisker = min,
    upper whisker = max,
    lower quartile = fq,
    upper quartile = tq,
    median=median},
    boxplot prepared]
coordinates {};
%
}

\begin{document}

\pgfplotstableread{
x   min qu2 fq  median  tq  max mean
a1  19.9    21.384  25.175  28.05   31.425  44.6    28.366
a2  22.4    24  26.975  29.4    31.65   45.6    29.509
a3  29.1    29.398  32.1    34.9    38.175  48.9    35.582
b1  33.5    34.494  41.3    46.15   54.725  108.1   49.749
b2  39.2    41.662  52.625  64.1    83.3    126.3   69.364
b3  42.7    45.092  66.2    80.05   102.8   213.2   88.251
c1  54.4    56.76   75.5    107.9   135.45  195.7   109.501
c2  54.7    59  96.8    123.45  152.725 331.2   132.139
c3  64.7    65.99   102.95  139 200.025 348.2   153.915
d1  74.4    86.818  136.9   176.25  221.925 503.4   189.913
d2  80.6    100.508 144.175 191.7   247.5   454.1   205.501
d3  73.3    110.804 174.15  227.5   294.7   632.3   247.584
e1  98.2    111.55  163.1   222.15  300.05  512.4   240.966
e2  110.9   112.768 181.125 236.4   325.975 719.3   266.793
}{\loadedtable}


\begin{tikzpicture}
\begin{axis}[
             boxplot/draw direction=y,
             boxplot/average={auto},
             boxplot/every average/.style={/tikz/mark=*,mark size=1},
             ymin=0,ymax=800]
\boxplotprepared{\loadedtable}{a1}
\boxplotprepared{\loadedtable}{a2}
\boxplotprepared{\loadedtable}{a3}
\boxplotprepared{\loadedtable}{b1}
\boxplotprepared{\loadedtable}{b2}
\boxplotprepared{\loadedtable}{b3}
\boxplotprepared{\loadedtable}{c1}
\boxplotprepared{\loadedtable}{c2}
\boxplotprepared{\loadedtable}{c3}
\boxplotprepared{\loadedtable}{d1}
\boxplotprepared{\loadedtable}{d2}
\boxplotprepared{\loadedtable}{d3}
\boxplotprepared{\loadedtable}{e1}
\end{axis}
\end{tikzpicture}


\end{document}

如果有人知道更简单(即更易读)的解决方案,或者可以发布更好的(更清晰或更准确)的解释来说明我的解决方案为何有效,请发布它,我会接受您的答案。

相关内容