6

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}
6
  • Could you strip this down a bit so that it's more minimal?
    – cmhughes
    May 4, 2012 at 10:45
  • Do you mean including the data into the code? It seems fairly minimal to me.
    – M. Toya
    May 4, 2012 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, 2012 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, 2012 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.
    – M. Toya
    May 7, 2012 at 17:19

1 Answer 1

4
+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}
3
  • 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.
    – M. Toya
    May 10, 2012 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, 2012 at 13:59
  • Ah yes, sorry, didn't see your edit when I wrote my comment.
    – Jake
    May 10, 2012 at 13:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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