[Tex/LaTex] Consistent distance between bar plot groups of different sizes

pgfplotsspacingtikz-pgf

I'm trying to make a bar plot where i always have one single bar paired against multiple bars. Two problems arise — first, the first bar is assumed to have 6 other bar buddies and gets pushed to the left. I am aware that this has been answered here, but there's more. The second problem is, assuming that solution (2nd MWE) I get an absurd ammount of wasted white space between groups. Any ideas on how to achieve even spacing between bar groups and plot edges? Dirty hacks and manual approaches are fine if needed be.

\documentclass[border=5pt]{standalone}

\usepackage{pgfplots}
    \pgfplotsset{compat=newest}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    ybar,
    width=12cm,
    xmin=0,xmax=2,
    enlarge x limits=0.3,
    ]
\addplot coordinates {
    (0,2.5) };
\addplot coordinates {
    (1,5) (2,7) };
\addplot coordinates {
    (1,4) (2,10) };
\addplot coordinates {
    (1,5) (2,8) };
\addplot coordinates {
    (1,2) (2,6) };
\addplot coordinates {
    (1,8) (2,10) };
\addplot coordinates {
    (1,7) (2,4) };
\end{axis}
\end{tikzpicture}
\end{document}

\documentclass[border=5pt]{standalone}

\usepackage{pgfplots}
    \pgfplotsset{compat=newest}

\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=0pt,
}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    plot1/.style={fill=red!20},
    plot2/.style={fill=blue!20},
    ybar,
    width=12cm,
    xmin=0,xmax=2,
    enlarge x limits=0.2,
    ]
\addplot [bar group size={5}{6}] coordinates {
    (0,2.5) };
\addplot [plot1,bar group size={0}{6}] coordinates {
    (1,5) (2,7) };
\addplot [plot2,bar group size={1}{6}] coordinates {
    (1,4) (2,10) };
\addplot [plot1,bar group size={2}{6}] coordinates {
    (1,5) (2,8) };
\addplot [plot2,bar group size={3}{6}] coordinates {
    (1,2) (2,6) };
\addplot [plot1,bar group size={4}{6}] coordinates {
    (1,8) (2,10) };
\addplot [plot2,bar group size={5}{6}] coordinates {
    (1,7) (2,4) };
\end{axis}
\end{tikzpicture}
\end{document}

Best Answer

I would use two separate axes for this that you position relative to each other.

With a few styles you can keep this very maintainable. In the code below, I've defined keys so that you only have to apply kynes left axis to the axis for the single bar, and kynes right axis to the axis for the groups of bars. You can set the gap between the groups of bars and between the axis and the bars using /pgfplots/group gap.

That plot was generated using:

\begin{tikzpicture}
\pgfplotsset{
    group size=6,
    group gap=0.5cm,
    /pgf/bar width=0.35cm
}
\begin{axis}[
    kynes left axis,
    ]
\addplot [fill=red, draw=black] coordinates {(0,2.5)};
\end{axis}
\begin{axis}[
    kynes right axis
    ]
\addplot [plot1] coordinates {
    (1,5) (2,7) };
\addplot [plot2] coordinates {
    (1,4) (2,10) };
\addplot [plot1] coordinates {
    (1,5) (2,8) };
\addplot [plot2] coordinates {
    (1,2) (2,6) };
\addplot [plot1] coordinates {
    (1,8) (2,10) };
\addplot [plot2] coordinates {
    (1,7) (2,4) };
\end{axis}
\end{tikzpicture}

Here's the complete code:

\documentclass[border=5pt]{standalone}

\usepackage{pgfplots}
    \pgfplotsset{compat=newest}

\begin{document}

\pgfplotsset{
    group gap/.initial=0.75cm,
    group size/.initial=6,
    kynes axis/.style={
        plot1/.style={fill=red!20},
        plot2/.style={fill=blue!20},
        ybar=0pt, % No gap between bars
        ymin=0, ymax=11,
    },
    kynes left axis/.style={
            kynes axis,
        name=kynes left axis,
            axis y line*=left,
        clip=false,
        xmin=-0.5, xmax=0.5,
        xtick=data,
        x=\pgfkeysvalueof{/pgf/bar width},
        enlarge x limits={abs=\pgfkeysvalueof{/pgfplots/group gap}, lower}
    },
    kynes right axis/.style={
            kynes axis,
            at=(kynes left axis.east),
            anchor=west,
            axis y line*=right,
            xtick=data,
            ytick=\empty,
            x=\pgfkeysvalueof{/pgfplots/group size}*\pgfkeysvalueof{/pgf/bar width}+\pgfkeysvalueof{/pgfplots/group gap},
            enlarge x limits={abs=\pgfkeysvalueof{/pgfplots/group size}/2*\pgfkeysvalueof{/pgf/bar width}+\pgfkeysvalueof{/pgfplots/group gap}},
    }
}

\begin{tikzpicture}
\pgfplotsset{
    group size=6,
    group gap=0.5cm,
    /pgf/bar width=0.35cm
}
\begin{axis}[
    kynes left axis,
    ]
\addplot [fill=red, draw=black] coordinates {(0,2.5)};
\end{axis}
\begin{axis}[
    kynes right axis
    ]
\addplot [plot1] coordinates {
    (1,5) (2,7) };
\addplot [plot2] coordinates {
    (1,4) (2,10) };
\addplot [plot1] coordinates {
    (1,5) (2,8) };
\addplot [plot2] coordinates {
    (1,2) (2,6) };
\addplot [plot1] coordinates {
    (1,8) (2,10) };
\addplot [plot2] coordinates {
    (1,7) (2,4) };
\end{axis}
\end{tikzpicture}
\end{document}
Related Question