# How can i create bar plot groups of different sizes in pgfplots?

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,
]
coordinates {(1930,50e6) (1940,33e6) (1950,40e6) (1960,50e6) (1970,70e6)};
coordinates {(1930,38e6) (1950,43e6) (1960,45e6) (1970,65e6)};
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?

-
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

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

\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},
]
coordinates {(1930,50e6) (1950,40e6) (1970,70e6)};
coordinates {(1930,38e6) (1950,43e6) (1970,65e6)};
coordinates {(1930,15e6) (1950,13e6) (1970,35e6)};

coordinates { (1940,33e6)  };
%SKIP second
%
coordinates { (1940,12e6)  };

coordinates { (1960,50e6) };
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).

-
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
@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