0

Below is a simple example of a stacked bar chart from the pgfplots manual.

In my case, the y axis represent percentages, and the percentages in all columns add up to 100 (so like in this example, all bars have the same height). However, the absolute number of items in each group differs. For example, I have 200 samples for tool1 but 500 for tool2. I would like to modify the bar width as a function of the total number of samples in each group, so that the bars for larger groups are wider.

I am aware of bar width. However, the \addplot macro defines all coordinates for, e.g., the blue parts, so setting bar width on the first \addplot changes the widths of all the blue bar parts. What I want instead is a way to set the width of an entire column.

Is there a way to do this? Ideally, the width is computed automatically, but it would be fine if I would have to set the width for each column manually.

enter image description here

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=1.18}

\begin{document}

\begin{tikzpicture}
  \begin{axis}[
    ybar stacked,
    symbolic x coords={tool1,tool2,tool3,tool4,tool5,tool6,tool7},
    xtick=data,
    x tick label style={rotate=45,anchor=east}]
  \addplot+ [ybar] coordinates {(tool1,0) (tool2,2) (tool3,2) (tool4,3) (tool5,0) (tool6,2) (tool7,0)};
  \addplot+ [ybar] coordinates {(tool1,0) (tool2,0) (tool3,0) (tool4,3) (tool5,1) (tool6,1) (tool7,0)};
  \addplot+ [ybar] coordinates {(tool1,6) (tool2,6) (tool3,8) (tool4,2) (tool5,6) (tool6,5) (tool7,6)};
  \addplot+ [ybar] coordinates {(tool1,4) (tool2,2) (tool3,0) (tool4,2) (tool5,3) (tool6,2) (tool7,4)};
  \end{axis}
\end{tikzpicture}

\end{document}

1 Answer 1

0

This is something that kind of works, but isn't very neat and requires some manual tweaking.

I use a regular bar chart and place multiple bars behind each other with bar shift=0pt. I define one plot for each bar part (in this example 4*7 plots in total), so that each plot can have its width manipulated individually. \addbar adds the data for a single bar, rather than a plot, and allows to set the width separately.

I needed to redefine the cycle list to use the same number of items as the number of plots for each bar. The cycle list is also reversed from its default definition, because the highest bar part comes first in this approach.

Note that unlike with ybar stacked, there is a 0-height bar part visible when the data has a 0 (e.g. the blue part for tool1, tool5, and tool7). There are undoubtedly other problems with this approach, and I still welcome other solutions, but maybe this is useful for someone.

enter image description here

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=1.18}

\begin{document}

\begin{tikzpicture}
  \begin{axis}[
      ybar,
      % X axis
      % We cannot use symbolic x coords because then we cannot use math expressions in coordinate definitions.
      xtick={1,2,3,4,5,6,7},
      xticklabels={tool1,tool2,tool3,tool4,tool5,tool6,tool7},
      x tick label style={rotate=45,anchor=east},
      cycle list={%
        {black,fill=gray,mark=none},%
        {brown!60!black,fill=brown!30!white,mark=none},%
        {red,fill=red!30!white,mark=none},%
        {blue,fill=blue!30!white,mark=none}%
        }]

    \def\addbar#1#2#3#4#5#6{% #1: index, #2: width, #3-6: values
      \addplot+[bar shift=0pt,bar width=#2] coordinates { (#1,#3+#4+#5+#6) };
      \addplot+[bar shift=0pt,bar width=#2] coordinates { (#1,#3+#4+#5) };
      \addplot+[bar shift=0pt,bar width=#2] coordinates { (#1,#3+#4) };
      \addplot+[bar shift=0pt,bar width=#2] coordinates { (#1,#3) };
    }

    \addbar{1}{10pt}{0}{0}{6}{4}
    \addbar{2}{20pt}{2}{0}{6}{2}
    \addbar{3}{10pt}{2}{0}{8}{0}
    \addbar{4}{20pt}{3}{3}{2}{2}
    \addbar{5}{10pt}{0}{1}{6}{3}
    \addbar{6}{20pt}{2}{1}{5}{2}
    \addbar{7}{10pt}{0}{0}{6}{4}
  \end{axis}
\end{tikzpicture}

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .