2

This question is basically a continuation of this answer. How can I handle outlier data in PGF boxplots, supposed my input table looks like this:

\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

The complete MWE would look like this:

\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}

It would also be the option to restructure my input table if this helps a more convenient solution.

0

1 Answer 1

1

You cannot simply read a table from a macro due to expansion issues. Instead, I would recommend that you have a look at the macro \pgfplotstabletranspose which may come quite handy here. You can specify the columns that should be selected before transposition via the option columns.

I think, what you are trying to get is the following (thanks for pointing to the issue regarding the selection of the 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}

enter image description here

2
  • 1
    Thank you for the hint! We are almost there. If you change table {\datatableoutliers} to table [y=#1] {\datatableoutliers}, the respective column will be selected. Commented Jul 27, 2022 at 17:21
  • You are right! I didn’t check. I will adjust my answer then. Commented Jul 27, 2022 at 20:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .