[Tex/LaTex] Read boxplot prepared values from a table

boxplotpgfplotspgfplotstable

Update: Is there any possibility of drawing two box plots this way using a single datatable as in the updated MWE below?


I'm trying to use pgfplots 1.8's shiny new boxplot feature. As I am also showing the boxplot data in a table, I have the values pre-computed in R and written to an external file. So now I am trying to use the boxplot prepared with a data table rather than hard-coded values, but with very little effect.

My paltry first try at an MWE (taken nearly verbatim from section 5.9.1
Box Plots
on p. 373 of the pgfmanual 1.8) is below. In essence, I was hoping to specify the column for the individual boxplot elements similar to the way you specify the x and y column when plotting a table (e.g. \addplot table[x=dof,y=L2] {datafile.dat};). However, I get a

! Package PGF Math Error: Unknown function 'lw' (in 'lw').

\documentclass[crop=false]{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.8}
\usepgfplotslibrary{statistics}
\begin{document}
\begin{tikzpicture}
\begin{axis}[boxplot/draw direction=y]
  \addplot+[
    boxplot prepared={
      lower whisker=lw,
      lower quartile=lq,
      median=med,
      upper quartile=uq,
      upper whisker=uw,
    },
  ]
  table[y index=0] {
    lw lq med  uq uw
     5  7 8.5 9.5 10
     4  5 6.5 8.5 9.5
  };
\end{axis}
\end{tikzpicture}
\end{document}

The hard-coded equivalent to this would be

\documentclass[crop=false]{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.8}
\usepgfplotslibrary{statistics}
\begin{document}
\begin{tikzpicture}
\begin{axis}[boxplot/draw direction=y]
  \addplot+[
    boxplot prepared={
      lower whisker=5,
      lower quartile=7,
      median=8.5,
      upper quartile=9.5,
      upper whisker=10,
    },
  ] coordinates{};
\end{axis}
\end{tikzpicture}
\end{document}

The coordinates{} is needed as pgfplots expects a list of outliers after the initial boxplot specification and baulks at an empty table{} statement.

Best Answer

The table in an \addplot command using the boxplot plot type is only used for providing raw data (if using boxplot) or outlier data (if using boxplot prepared), but not the box parameters. Those always need to be provided directly using the boxplot prepared={...} options.

You can, however, write a couple of wrapper styles that read the values from a table and set the required keys. That would allow you to write something like

\addplot+[
  boxplot prepared from table={
    table=\datatable,
    lower whisker=lw,
    upper whisker=uw,
    lower quartile=lq,
    upper quartile=uq,
    median=med
  }, boxplot prepared
  ]
  coordinates {};
\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
  ]
  coordinates {};

to get


\documentclass[crop=false]{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.8}
\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{
    lw lq med  uq uw
     5  7 8.5 9.5 10
     4  5 6.5 8.5 9.5
}\datatable


\begin{document}
\begin{tikzpicture}
\begin{axis}[boxplot/draw direction=y]
  \addplot+[
  boxplot prepared from table={
    table=\datatable,
    lower whisker=lw,
    upper whisker=uw,
    lower quartile=lq,
    upper quartile=uq,
    median=med
  }, boxplot prepared
  ]
  coordinates {};
  \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
  ]
  coordinates {};
\end{axis}
\end{tikzpicture}
\end{document}