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.

One can easily create "groups" of bar plots using the ybar/xbar attribute for the axis environment. When multiple \addplot commands are issued using the same x/y coordinate, the entire group of bar plots for one coordinate is then centered on that coordinate. However, this seems to require that the same number of bar plots is used in every group. Is there any way to relax this condition?

Modified example from the pgfplots documentation:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[
        width=0.95*\textwidth,
        x tick label style={/pgf/number format/1000 sep=},
        ylabel=Population,
        enlargelimits=0.15,
        legend style={at={(0.5,-0.15)},
        anchor=north,legend columns=-1},
        ybar,
        bar width=7pt,
        ]
        \addplot
        coordinates {(1930,50e6) (1940,33e6) (1950,40e6) (1960,50e6) (1970,70e6)};
        \addplot
        coordinates {(1930,38e6) (1950,43e6) (1960,45e6) (1970,65e6)};
        \addplot
        coordinates {(1930,15e6) (1940,12e6) (1950,13e6) (1970,35e6)};
        \legend{Far,Near,Here,Annot}
    \end{axis}
\end{tikzpicture}

\end{document}

The numbers that were left out appear as gaps within the groups of bar plots. Is there any way to change that behaviour?

enter image description here

share|improve this question
    
In this specific case you could reorder the plots so that the first gap is on the left and the second gap is on the right, so no gap is visible. So swapping the first two \addplots works. –  Peter Grill Feb 8 '12 at 15:32
    
@PeterGrill that would only solve parts of the problem. The groups would still not be centered correctly, as the "gap" is still there (though not in the middle of any group) –  barbaz Feb 8 '12 at 15:37
add comment

1 Answer

up vote 6 down vote accepted

In order to find and close "gaps" automatically, the shift for single bars would need to be reevaluated for every coordinate (combined with some trivial counting operations which are fairly simple in pgfplots). However, pgfplots supports only uniform bar shift, i.e. one shift for all coordinates of a single bar plot (\addplot command). This limitation is inherited from pgf (and would need some more time to fix).

A simple alternative is to regroup and configure your groups manually. A solution could be

enter image description here

\documentclass{article}

\usepackage{pgfplots}

\pgfplotsset{compat=1.3}

\pgfplotsset{
    % #1: index in the group(0,1,2,...)
    % #2: number of plots of that group
    bar group size/.style 2 args={
        /pgf/bar shift={%
                % total width = n*w + (n-1)*skip
                % -> subtract half for centering
                -0.5*(#2*\pgfplotbarwidth + (#2-1)*\pgfkeysvalueof{/pgfplots/bar group skip})  + 
                % the '0.5*w' is for centering
                (.5+#1)*\pgfplotbarwidth + #1*\pgfkeysvalueof{/pgfplots/bar group skip}},%
    },
    bar group skip/.initial=2pt,
    plot 0/.style={blue,fill=blue!30!white,mark=none},%
    plot 1/.style={red,fill=red!30!white,mark=none},%
    plot 2/.style={brown!60!black,fill=brown!30!white,mark=none},%
}

\begin{document}
\thispagestyle{empty}

\begin{tikzpicture}
    \begin{axis}[
        width=0.95*\textwidth,
        x tick label style={/pgf/number format/1000 sep=},
        ylabel=Population,
        enlargelimits=0.15,
        legend style={at={(0.5,-0.15)},
        anchor=north,legend columns=-1},
        ybar,
        bar width=7pt,
        xtick={1930,1940,1950,1960,1970},
        ]
        \addplot[plot 0,bar group size={0}{3}]
        coordinates {(1930,50e6) (1950,40e6) (1970,70e6)};
        \addplot[plot 1,bar group size={1}{3}]
        coordinates {(1930,38e6) (1950,43e6) (1970,65e6)};
        \addplot[plot 2,bar group size={2}{3}]
        coordinates {(1930,15e6) (1950,13e6) (1970,35e6)};

        \addplot[plot 0,bar group size={0}{2}]
        coordinates { (1940,33e6)  };
        %SKIP second
        %
        \addplot[plot 2,bar group size={1}{2}]
        coordinates { (1940,12e6)  };

        \addplot[plot 0,bar group size={0}{2}]
        coordinates { (1960,50e6) };
        \addplot[plot 1,bar group size={1}{2}]
        coordinates { (1960,45e6) };
        %SKIP third
        %

        \legend{Far,Near,Here}
    \end{axis}
\end{tikzpicture}

\end{document}

I applied the following changes to your code:

  1. I introduced the style bar group size={index}{group size} .

  2. I regrouped your 3 bar plots into different \addplot commands such that each group has the same set of x coordinates.

  3. I disabled the cycle list and provided options explicitly.

Note that the computed bar shift and gap between adjacent bars has been copied (with obvious modifications) from the pgfplots manual (compare the /pgfplots/ybar docs).

share|improve this answer
    
Nice, thanks a lot! I guess since every bar needs its own /pgf/bar shift there is no easy way to modify this approach such that each group of bars could be produced from a single table? Ideally with only the bar heights contained in the table? –  barbaz Feb 9 '12 at 10:26
1  
@barbaz Well, at least my approach to think about "an easy way" got stuck when I realized that pgf has one shift which is applied to all coordinates simultaneously. Of course, one could write some scripts (in tex or whatever) which generates my output. Nevertheless, I do not have one at hand. –  Christian Feuersänger Feb 9 '12 at 17:38
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.