Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to create notched box plots similar to those shown in the picture from data files. enter image description here

I have managed code that creates the box plots with notches like I want (the code below without the axis and addplot commands), but am having trouble adding axes. My setup for drawing the box plots does not work when I use \addplot and if I don't use \addplot I get other errors or depending on how I move the code for my axis, I get only the axes. I cannot think how to fix this.

\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}
\usepackage{pgfplotstable}
\usetikzlibrary{calc}
\begin{document}
\begin{filecontents}{boxplot.dat}
1 1 1.2 0.4 1.5 0.2 1.05 0.95
2 2 2.3 1.5 2.7 1 2.05 1.95
3 0.7 1.4 0.5 1.9 0.1 0.75 0.65
4 0.7 1.4 0.5 1.9 0.1 0.75 0.65
\end{filecontents}
\pgfplotstableread{boxplot.dat}{\infotable}
\pgfplotstablegetrowsof{boxplot.dat}
\pgfmathsetmacro{\rows}{\pgfplotsretval-1}
\begin{tikzpicture}
\begin{axis}[
xticklabels={1, 2, 3, 4},
]
\addplot{
\foreach \i in {0,...,\rows}{%
%x-values
\pgfplotstablegetelem{\i}{[index] 0}\of{\infotable}
%Middle
\let\xM\pgfplotsretval
%Left
\pgfmathsetmacro{\xL}{\xM-0.25}
\pgfmathsetmacro{\xLInd}{\xM-0.125}
%Right
\pgfmathsetmacro{\xR}{\xM+0.25}
\pgfmathsetmacro{\xRInd}{\xM+0.125}
%y-values
\pgfplotstablegetelem{\i}{[index] 4}\of{\infotable}
\let\yTopWhisk\pgfplotsretval
\pgfplotstablegetelem{\i}{[index] 2}\of{\infotable}
\let\yBoxTop\pgfplotsretval
\pgfplotstablegetelem{\i}{[index] 6}\of{\infotable}
\let\yTopInd\pgfplotsretval
\pgfplotstablegetelem{\i}{[index] 1}\of{\infotable}
\let\yMedian\pgfplotsretval
\pgfplotstablegetelem{\i}{[index] 7}\of{\infotable}
\let\yBottomInd\pgfplotsretval
\pgfplotstablegetelem{\i}{[index] 3}\of{\infotable}
\let\yBoxBottom\pgfplotsretval
\pgfplotstablegetelem{\i}{[index] 5}\of{\infotable}
\let\yBottomWhisk\pgfplotsretval
%top part
\draw [blue] (\xLInd,\yMedian) -- (\xL,\yTopInd) -- (\xL,\yBoxTop) -- (\xR,\yBoxTop) --       (\xR,\yTopInd) -- (\xRInd,\yMedian);
%bottom part
\draw [blue] (\xLInd,\yMedian) -- (\xL,\yBottomInd) -- (\xL,\yBoxBottom) -- (\xR,\yBoxBottom) -- (\xR,\yBottomInd) -- (\xRInd,\yMedian);
%median
\draw [red] (\xLInd,\yMedian) -- (\xRInd,\yMedian);
%top whisker
\draw [black] (\xM,\yBoxTop) -- (\xM,\yTopWhisk);
\draw [black] (\xL,\yTopWhisk) -- (\xR,\yTopWhisk);
%bottom whisker
\draw [black] (\xM,\yBoxBottom) -- (\xM,\yBottomWhisk);
\draw [black] (\xL,\yBottomWhisk) -- (\xR,\yBottomWhisk);
}%
}
\end{axis}
\end{tikzpicture}
\end{document}
share|improve this question
    
Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. Could you find a picture of what you would like to happen? –  Sean Allred Aug 1 '13 at 16:00
1  
I added a picture. I couldn't before -- I didn't have enough reputation. –  MinnieMouse Aug 1 '13 at 16:23
add comment

1 Answer

up vote 5 down vote accepted

Since version 1.8, PGFPlots can draw boxplots out of the box (pardon the pun). You can add the ability to draw notches relatively easily, and you can use the approach from Read boxplot prepared values from a table to provide the values from a table.

The above image is generated using

\pgfplotstableread{
    lw lq med  uq uw  ln  un
     5  7 8.5 9.5 10  8.0 9.0
     4  5 6.5 8.5 9.5 5.5 7.2
}\datatable

\begin{tikzpicture}
\begin{axis}[
    boxplot/draw direction=y, 
    x=2cm,
    boxplot/box extend=0.3,
    boxplot/notch width=0.5
]
  \addplot +[
        boxplot prepared from table={
        table=\datatable,
        lower whisker=lw,
        upper whisker=uw,
        lower quartile=lq,
        upper quartile=uq,
        lower notch=ln,
        upper notch=un,
        median=med
    }, boxplot prepared
 ] coordinates {(1,4)};
  \addplot +[
            boxplot prepared from table={
        table=\datatable,
        row=1,
        lower whisker=lw,
        upper whisker=uw,
        lower quartile=lq,
        upper quartile=uq,
        lower notch=ln,
        upper notch=un,
        median=med
    }, boxplot prepared
  ] coordinates {(2,11) (2,11.5)};
\end{axis}
\end{tikzpicture}

And here's the complete code:

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepgfplotslibrary{statistics}
\begin{document}

\makeatletter
\pgfplotsset{
    boxplot/lower notch/.initial=\pgfutil@empty,
    boxplot/upper notch/.initial=\pgfutil@empty,
    boxplot/notch width/.initial=0.9,
    boxplot/draw/box/.code={%
        \draw[/pgfplots/boxplot/every box/.try]
            (boxplot box cs:\pgfplotsboxplotvalue{lower quartile},0)
            -- (boxplot box cs:\pgfplotsboxplotvalue{lower notch},0)
            -- (boxplot box cs:\pgfplotsboxplotvalue{median},0.5-\pgfplotsboxplotvalue{notch width}/2)
            -- (boxplot box cs:\pgfplotsboxplotvalue{upper notch},0)
            -- (boxplot box cs:\pgfplotsboxplotvalue{upper quartile},0)
            -- (boxplot box cs:\pgfplotsboxplotvalue{upper quartile},1)
            -- (boxplot box cs:\pgfplotsboxplotvalue{upper notch},1)
            -- (boxplot box cs:\pgfplotsboxplotvalue{median},0.5+\pgfplotsboxplotvalue{notch width}/2)
            -- (boxplot box cs:\pgfplotsboxplotvalue{lower notch},1)
            -- (boxplot box cs:\pgfplotsboxplotvalue{lower quartile},1)
            -- cycle
        ;
    },%
    boxplot/draw/median/.code={%
        \draw[/pgfplots/boxplot/every median/.try]
            (boxplot box cs:\pgfplotsboxplotvalue{median},0.5-\pgfplotsboxplotvalue{notch width}/2)
            --
            (boxplot box cs:\pgfplotsboxplotvalue{median},0.5+\pgfplotsboxplotvalue{notch width}/2)
        ;
    },%
        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
}

\pgfplotstableread{
    lw lq med  uq uw  ln  un
     5  7 8.5 9.5 10  8.0 9.0
     4  5 6.5 8.5 9.5 5.5 7.2
}\datatable

\begin{tikzpicture}
\begin{axis}[
    boxplot/draw direction=y, 
    x=2cm,
    boxplot/box extend=0.3,
    boxplot/notch width=0.5
]
  \addplot +[
        boxplot prepared from table={
        table=\datatable,
        lower whisker=lw,
        upper whisker=uw,
        lower quartile=lq,
        upper quartile=uq,
        lower notch=ln,
        upper notch=un,
        median=med
    }, boxplot prepared
 ] coordinates {(1,4)};
  \addplot +[
            boxplot prepared from table={
        table=\datatable,
        row=1,
        lower whisker=lw,
        upper whisker=uw,
        lower quartile=lq,
        upper quartile=uq,
        lower notch=ln,
        upper notch=un,
        median=med
    }, boxplot prepared
  ] coordinates {(2,11) (2,11.5)};
\end{axis}
\end{tikzpicture}

\end{document}
share|improve this answer
2  
Cool answer! However, the row key is never set, i.e. it is always 0. Perhaps you should make it mandatory in your custom style (which appears to be a good addition which is missing in pgfplots, by the way). –  Christian Feuersänger Aug 1 '13 at 20:12
    
Thanks a lot! It works perfectly! –  MinnieMouse Aug 2 '13 at 9:43
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.