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 a figure with two bar graphs with bars grouped two by two. I use bar width and bar shift to separate the bars. My problem is that I want to add error bars to these plots but I do not know how to make them follow the bars. All I get are couples of bars (good!) but with couples of error bars between them (awkward!).

How could I have the error bars in the middle of the data bars without manually shifting them?

My current attempt:

\documentclass{article}

\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

    \begin{tikzpicture}

    \pgfplotstableread{
    1 4   0.2  0.1
    2 4.2 0.1  0.5
    3 3.1 0.3  0.4
    4 2.5 0.25 0.35
    }\tablei

    \pgfplotstableread{
    1 3.5 0.1  0.3
    2 3.8 0.2  0.2
    3 4.0 0.25 0.25
    4 3.0 0.3  0.5
    }\tablet

    % Bar styles
    \pgfplotsset{shifti/.style={mark=no markers, bar width=4pt, bar shift=3pt}}
    \pgfplotsset{shiftt/.style={mark=no markers, bar width=4pt, bar shift=-3pt}}

    % Error styles
    \pgfplotsset{err/.style={forget plot, draw=none}} 
    \pgfplotsset{errp/.style={err, error bars/.cd,x dir=plus,  x explicit}}
    \pgfplotsset{errm/.style={err, error bars/.cd,x dir=minus, x explicit}}

    \begin{axis}[%
    /pgfplots/table/header=false,
    scale only axis,
    width=12cm,
    height=8cm,
    axis on top]

    \addplot+[xbar, shifti] table[x index=1, y index=0]{\tablei};
    \addplot+[no markers, errm] table[x index=1, y index=0, x error index=2]{\tablei};
    \addplot+[no markers, errp] table[x index=1, y index=0, x error index=3]{\tablei};

    \addplot+[xbar, shiftt] table[x index=1, y index=0]{\tablet};
    \addplot+[no markers, errm] table[x index=1, y index=0, x error index=2]{\tablet};
    \addplot+[no markers, errp] table[x index=1, y index=0, x error index=3]{\tablet};

    \end{axis}
    \end{tikzpicture}

\end{document}
share|improve this question
    
Could you strip this down a bit so that it's more minimal? –  cmhughes May 4 '12 at 10:45
    
Do you mean including the data into the code? It seems fairly minimal to me. –  Alfred M. May 4 '12 at 11:51
    
A couple of things: 1) It would be good to have just one code block that can be copied and pasted, instead of two tex files and two datafiles. You can include the data in your document using the \begin{filecontents}{<filename>}...\end{filecontents} environment. 2) You seem to be happy to shift the bars manually (instead of just supplying xbar to the axis, which would take care of the offset automatically). Why don't you want to shift the error bars in the same way? –  Jake May 7 '12 at 8:20
    
3) Your errors seem to be different in positive and negative directions, both absolutely and relatively to the data value. Is this intentional? Could you explain the nature of these asymmetric errors (that might help with coming up with a "proper" automated solution)? –  Jake May 7 '12 at 8:30
    
1) I'll provide a simpler example as soon as possible. 2) Using xbar in the axis declaration does not give the wanted result because I fail to prevent the (data) bars associated with the plots for the error bars to be drawn. I tried to shift manually the error bars but with no success. –  Alfred M. May 7 '12 at 17:19

1 Answer 1

up vote 3 down vote accepted
+50

The simplest way to position the error bars correctly is to use yshift=<value> to shift the error bars up or down. If you use the same <value> that you used for the bar shift, the error bars will be positioned correctly. A "proper" automatic solution in this case would require support for asymmetric error bars, which isn't currently possible with pgfplots. It might be worth opening a feature request for this.

\documentclass{article}

\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\begin{figure}
    \begin{tikzpicture}

    \pgfplotstableread{
    1 4   0.2  0.1
    2 4.2 0.1  0.5
    3 3.1 0.3  0.4
    4 2.5 0.25 0.35
    }\tablei

    \pgfplotstableread{
    1 3.5 0.1  0.3
    2 3.8 0.2  0.2
    3 4.0 0.25 0.25
    4 3.0 0.3  0.5
    }\tablet

    % Bar styles
    \pgfplotsset{shifti/.style={mark=no markers, bar width=4pt, bar shift=3pt}}
    \pgfplotsset{shiftt/.style={mark=no markers, bar width=4pt, bar shift=-3pt}}

    % Error styles
    \pgfplotsset{err/.style={forget plot, draw=none}} 
    \pgfplotsset{errp/.style={err, black, error bars/.cd,x dir=plus,  x explicit}}
    \pgfplotsset{errm/.style={err, black, error bars/.cd,x dir=minus, x explicit}}

    \begin{axis}[%
    /pgfplots/table/header=false,
    scale only axis,
    width=12cm,
    height=8cm,
    axis on top]

    \addplot+[xbar, shifti] table[x index=1, y index=0]{\tablei};
    \addplot+[no markers, yshift=3pt, errm] table[x index=1, y index=0, x error index=2]{\tablei};
    \addplot+[no markers, yshift=3pt, errp] table[x index=1, y index=0, x error index=3]{\tablei};

    \addplot+[xbar, shiftt] table[x index=1, y index=0]{\tablet};
    \addplot+[no markers, yshift=-3pt, errm] table[x index=1, y index=0, x error index=2]{\tablet};
    \addplot+[no markers, yshift=-3pt, errp] table[x index=1, y index=0, x error index=3]{\tablet};

    \end{axis}
    \end{tikzpicture}

\end{figure}

\end{document}
share|improve this answer
    
Using a macro for the shift amount makes it less cumbersome to edit. It is not perfectly `streamlined' but it does the job with limited hassle. Support for assymetric error bars would be nice indeed. –  Alfred M. May 10 '12 at 13:50
    
Yes, that's a good idea. It would be ideal if the error bars could be specified as part of the actual bar plot, instead of using extra \addplot commands, but that will require a bit of work. –  Jake May 10 '12 at 13:59
    
Ah yes, sorry, didn't see your edit when I wrote my comment. –  Jake May 10 '12 at 13:59

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.