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 have been using this box plot code to great effect recently. I am making a large amount of plots in my thesis and would like to be able to do the following data format:

\begin{filecontents}{dataOne.dat}
%x whiskerbottom boxbottom median boxtop whiskertop 
 0  -0.573413   -0.528268   -0.641948 -0.483655 -0.794368   
 1  -0.673413   -0.628268   -0.741948 -0.583655 -0.894368       
\end{filecontents}

etc.

This is how \boxplot is defined:

\newcommand{\boxplot}[2][]{
    \addplot [box plot median,#1] table {#2};
    \addplot [forget plot, box plot box,#1] table {#2};
    \addplot [forget plot, box plot top whisker,#1] table {#2};
    \addplot [forget plot, box plot bottom whisker,#1] table {#2};
}

I am adding these to my plot using:

\begin{tikzpicture}
\begin{axis} [xtick={0,1},  xmin=-1,  xmax =2,  xticklabels={test,test2},   box plot width=5mm]
\boxplot [black, forget plot]{dataOne.dat}
\addplot[color = black, mark = *, nodes near coords,every node near coord/.style={anchor=180}]coordinates {( 0, -1)};

\end{axis}
\end{tikzpicture}

How can I use the \boxplot command to let me specify to ONLY use a specific row of the table, ie something like:

\boxplot [black, forget plot]{dataOne.dat,0}  %only use row 0
\boxplot [black, forget plot]{dataOne.dat}  % use entire datafile

so it would ONLY reference the first data row in dataOne.dat if passed. Otherwise I have to create separate datafiles to view just one or both box plots.

I know I need to modify:

table{#2}

to have some sort of conditional argument which is passed through the \boxplot creation, but I'm not really sure how to do this. The documentation here is way over my head and seems to focus exclusively on retrieving specific values for a specified column.

share|improve this question
add comment

1 Answer 1

up vote 2 down vote accepted

You can use an x filter/.code that checks whether the current \coordindex is equal to the desired row number, and if it's not, discard the coordinate:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{filecontents}

\begin{filecontents}{dataOne.dat}
%x whiskerbottom boxbottom median boxtop whiskertop 
 0  -0.573413   -0.528268   -0.641948 -0.483655 -0.794368   
 1  -0.673413   -0.628268   -0.741948 -0.583655 -0.894368       
\end{filecontents}

\pgfplotsset{
    box plot/.style={
        /pgfplots/.cd,
        black,
        only marks,
        mark=-,
        mark size=\pgfkeysvalueof{/pgfplots/box plot width},
        /pgfplots/error bars/y dir=plus,
        /pgfplots/error bars/y explicit,
        /pgfplots/table/x index=\pgfkeysvalueof{/pgfplots/box plot x index},
    },
    box plot box/.style={
        /pgfplots/error bars/draw error bar/.code 2 args={%
            \draw  ##1 -- ++(\pgfkeysvalueof{/pgfplots/box plot width},0pt) |- ##2 -- ++(-\pgfkeysvalueof{/pgfplots/box plot width},0pt) |- ##1 -- cycle;
        },
        /pgfplots/table/.cd,
        y index=\pgfkeysvalueof{/pgfplots/box plot box top index},
        y error expr={
            \thisrowno{\pgfkeysvalueof{/pgfplots/box plot box bottom index}}
            - \thisrowno{\pgfkeysvalueof{/pgfplots/box plot box top index}}
        },
        /pgfplots/box plot
    },
    box plot top whisker/.style={
        /pgfplots/error bars/draw error bar/.code 2 args={%
            \pgfkeysgetvalue{/pgfplots/error bars/error mark}%
            {\pgfplotserrorbarsmark}%
            \pgfkeysgetvalue{/pgfplots/error bars/error mark options}%
            {\pgfplotserrorbarsmarkopts}%
            \path ##1 -- ##2;
        },
        /pgfplots/table/.cd,
        y index=\pgfkeysvalueof{/pgfplots/box plot whisker top index},
        y error expr={
            \thisrowno{\pgfkeysvalueof{/pgfplots/box plot box top index}}
            - \thisrowno{\pgfkeysvalueof{/pgfplots/box plot whisker top index}}
        },
        /pgfplots/box plot
    },
    box plot bottom whisker/.style={
        /pgfplots/error bars/draw error bar/.code 2 args={%
            \pgfkeysgetvalue{/pgfplots/error bars/error mark}%
            {\pgfplotserrorbarsmark}%
            \pgfkeysgetvalue{/pgfplots/error bars/error mark options}%
            {\pgfplotserrorbarsmarkopts}%
            \path ##1 -- ##2;
        },
        /pgfplots/table/.cd,
        y index=\pgfkeysvalueof{/pgfplots/box plot whisker bottom index},
        y error expr={
            \thisrowno{\pgfkeysvalueof{/pgfplots/box plot box bottom index}}
            - \thisrowno{\pgfkeysvalueof{/pgfplots/box plot whisker bottom index}}
        },
        /pgfplots/box plot
    },
    box plot median/.style={
        /pgfplots/box plot,
        /pgfplots/table/y index=\pgfkeysvalueof{/pgfplots/box plot median index}
    },
    box plot width/.initial=1em,
    box plot x index/.initial=0,
    box plot median index/.initial=1,
    box plot box top index/.initial=2,
    box plot box bottom index/.initial=3,
    box plot whisker top index/.initial=4,
    box plot whisker bottom index/.initial=5,
    only row/.style={
            x filter/.code={\ifnum\coordindex=#1\else\def\pgfmathresult{nan}\fi}
    }
}

\newcommand{\boxplot}[2][]{
    \addplot [box plot median,#1] table {#2};
    \addplot [forget plot, box plot box,#1] table {#2};
    \addplot [forget plot, box plot top whisker,#1] table {#2};
    \addplot [forget plot, box plot bottom whisker,#1] table {#2};
}

\begin{document}
\begin{tikzpicture}
\begin{axis} [xtick={0,1},  xmin=-1,  xmax =2,  xticklabels={test,test2},   box plot width=5mm]
\boxplot [black, forget plot, only row=0]{dataOne.dat}
\boxplot [red, forget plot, only row=1]{dataOne.dat}
\addplot[color = black, mark = *, nodes near coords,every node near coord/.style={anchor=180}]coordinates {( 0, -1)};
\end{axis}
\end{tikzpicture}
\end{document}
share|improve this answer
    
This works. It also makes me wonder if there is a better way to do my data, because this requires some care in setting it up (which I guess is ok). –  enderland Mar 29 '13 at 23:17
    
@enderland: You could apply the filter to a particular column of your data, if that would make it easier. –  Jake Mar 29 '13 at 23:18
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.