File Exchange

image thumbnail

Plot Groups of Stacked Bars

version 1.0.0.0 (1.69 KB) by Evan
Generate a bar plot with multiple stacks grouped together.

99 Downloads

Updated 13 Sep 2011

View License

Plot a set of stacked bars, but group them according to labels provided.

Params:
stackData is a 3D matrix (i.e., stackData(i, j, k) => (Group, Stack, StackElement))
groupLabels is a CELL type (i.e., { 'a', 1 , 20, 'foo' };)

Cite As

Evan (2021). Plot Groups of Stacked Bars (https://www.mathworks.com/matlabcentral/fileexchange/32884-plot-groups-of-stacked-bars), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (65)

Rodrigo Bezerra

Great job. Works perfectly.

haibin niu

nice!thank you!

Christie Etukudor

Still very relevant; thank you

Loughlin DUDLEY

Eleonora Gajetti

Pierre-Emmanuel Oms

thank you works great !!

Vasia Papoutsaki

thank you!

P.V.

Adam Danz

The handle to the bars should be added as an output so users can manipulate the bar parameters.
Here's an example how to change the color of segments within each stack.

https://www.mathworks.com/matlabcentral/answers/371186-grouped-stacked-bar-with-specific-colours#answer_393160

Hanno Teiwes

zhang meng

Once you plot the data, you can easily customize the figure using "Figure Properties" from the "edit" ,enu. For instance, colors, name or scale (linear or log).

liu xiaoman

thank you very much!

justok

Marina Costantini

Qiquan Zhang

how to add legend? thank you very much! i am hurry

Qiquan Zhang

how to work?

Pushpa Dissanayake

thanks for your contribution, it's useful!

MatteP

Useful but a question.
How can I increase the distance between the x-tick label (to lable the groups) and the x-tick lebels (to lable the elements of the group)?

Itamar Cohen

Great and very useful. 10x.

Marleen Cobben

Thanks! Also for the color coding Tim!

Alessandro Rigazzi

katecl

Labels for individual bars are on the top b/c the Y coordinate for that text is set to the sum of all the columns. To label underneath the bars (and just under the line marking the x-axis), change the added code starting at line 36 to

for j=1:NumGroupsPerAxis

text(groupDrawPos(j),0,...
barLabels{i},'VerticalAlignment','cap',...
'HorizontalAlignment','center');

end

xyzmrsir

thanks

Alexandre Mangot

In response to the multiple comments regarding add label to individual bars, it appears that the labels is always shown at the top of the bars even though 'Bottom' was set for 'VerticalAlignment' - any reason why?

Andreas Albrecht

Adding the following line inside the for-loop does avoid unnecessary legend entries if you padded your data with zeros before calling this function.
Y = Y(:,any(Y,1));

Harish Suryanarayana

CHENHAO WANG

Anjum Rauf Meer

Tasnuba Siddiqui

Completly worked :), thank you for the awesome coding and sharing.

Patricia Stahn

paula

Thanks, useful.

Michail Schwab

Ikram Ashraf

Thanks, could you please tell me how to do:
i) How to increase the bar width seems that even setting the MaxGroupWidth = 1 it does not increase much.
ii) How to bring each label in the center of bars.
Thanks.

YI GU

?

add bar labels it work
function plotBarStackGroups(stackData, groupLabels)
%% Plot a set of stacked bars, but group them according to labels provided.
%%
%% Params:
%% stackData is a 3D matrix (i.e., stackData(i, j, k) => (Group, Stack, StackElement))
%% groupLabels is a CELL type (i.e., { 'a', 1 , 20, 'because' };)
%%
%% Copyright 2011 Evan Bollig (bollig at scs DOT fsu ANOTHERDOT edu
%%
%%

NumGroupsPerAxis = size(stackData, 1);
NumStacksPerGroup = size(stackData, 2);

% Count off the number of bins
groupBins = 1:NumGroupsPerAxis;
MaxGroupWidth = 0.65; % Fraction of 1. If 1, then we have all bars in groups touching
groupOffset = MaxGroupWidth/NumStacksPerGroup;
figure
hold on;
for i=1:NumStacksPerGroup

Y = squeeze(stackData(:,i,:));

% Center the bars:

internalPosCount = i - ((NumStacksPerGroup+1) / 2);

% Offset the group draw positions:
groupDrawPos(i,:) = (internalPosCount)* groupOffset + groupBins;

h = bar(Y, 'stacked');
set(h,'BarWidth',groupOffset);
set(h,'XData',groupDrawPos(i,:));
end
barLabels={'2000','2005','2010','2015'};

% Bar Labeling
for j=1:NumGroupsPerAxis
text(groupDrawPos(:,j),squeeze(sum(stackData(j,:,:),3)),...
barLabels,'VerticalAlignment','bottom',...
'HorizontalAlignment','center');
end
hold off;
set(gca,'XTickMode','manual');
set(gca,'XTick',1:NumGroupsPerAxis);
set(gca,'XTickLabelMode','manual');
set(gca,'XTickLabel',groupLabels);
end

Reinhard Kreuzer

Kumush

Thanks Evan! This is great ;-) I was wondering if there is a way to have log-scale on the y-axis? My groups are super heterogeneous, and I would like to plot them as logs (with base 10) against powes of 10 on the vertical. Many thanks.

Very useful function!

Figured out a solution for the labelling of individual columns:

Add as an input a cell array of strings:

barLabels={'column1name','column2name',etc...};

Then, on line 36, just before the 'end' of the for loop add the following lines:

% Bar Labeling
for j=1:NumGroupsPerAxis

text(groupDrawPos(j),sum(Y(j,:),2),...
barLabel{i},'VerticalAlignment','bottom',...
'HorizontalAlignment','center');

end

ys chen

Thanks, very handy function!

Eunice Li

ruffntuff

Hi, trying to add legend. Plot working as expected otherwise.

Looking at Beckah Rieck's post on 12 July '16, first step is to create a handle but...

Data
Z(:,:,1) = [EnCol'*2, EnAddDiurn'];
Z(:,:,2) = [zeros(12,1), EnAddSeas'];
(all variables are 12x1 doubles as you can see form zeros value)

Cmd to create handle
b = plotBarStackGroups(Z, months);

Error
Error using plotBarStackGroups
Too many output arguments.

Do you see what I'm doing wrong here?
Thanks in advance!

Alexander Kurz

Thanks for this Evan! Finally I would like to plot groups of stacked bars with error bars. Anyone already did it before?

regaieg rym

Hi

I want to produce the stackData matrix by my own values. Any ideas ?

Suehee Huh

Thanks!!!!

Beckah Rieck

Thanks Evan!

Emma- if you are talking about x-labels for what each bar means, just add a legend:
b = plotBarStackGroups(stackData, Month);
legend([b(1,1), b(2,1), b(2,2)], 'Total Added', 'Closed- Non Quick Hits', 'Closed- Quick Hits');

If you mean Y data labels on the bars, use text:
text(b(1,1).XData', zeros(size(b(1,1).XData')), labelsAddedtoQ);

(that places them at the base).

Ashrar Matin

Emma Jonasson

Thanks for the script. I would also like to add x-labels for each bar within the groups, anyone who can help me achieve that? Explaining from the example: above the label 'Test', I would like to add labels on the bars, e.g. 'a' 'b' 'c', and so on.

Emma Jonasson

Samy

thanks for the script, if you don't like the border of the plot being messed up just remove the 'hold on;' in line 20 and add 'if i == 1, hold on; end' after 'h(i,:) = bar(Y, 'stacked');'!

tan yu

Elizabeth

Oleg Komarov

If you have a 3D array A, then reshaping your array and interleaving groups with a row of NaNs will produce the same result:

sz = size(A);
B = [A, NaN(sz(1),1,sz(3))];
B = reshape(permute(B, [2,1,3]),sz(1)*(sz(2)+1),sz(3));
bar(C(1:end-1,:),'stacked')

ADITHYAN

Works very well. Thanks a lot evan.

Daniel Paiva

Very good.

Jenny

Vera

Ricardo

Very useful function!, thank you!

Tim

Berk, I had the same desire and found it was pretty simple to customize.

After this...
h(i,:) = bar(Y, 'stacked');

I added this...
set(h(i,1),'facecolor','y','edgecolor','k');
set(h(i,2),'facecolor','r','edgecolor','k');
set(h(i,3),'facecolor','c','edgecolor','k');
set(h(i,4),'facecolor','g','edgecolor','k');

...so that the base of each bar is always yellow, etc.

Doubt you'll need this 1 year later, but for the next rookie like myself, could be useful.

Thanks for the elegant and useful function, Evan.

Ben

Berk

Thanks, very handy function!

Could you please tell whether we can assign different colors to different stacks?
Currently, all the stack elements have the same color/type. However, I am wonering whether it would be possible to differentiate the different stacks?

Berk

grega

Nice one! Works! Example makes it clear! Thank you!

Evan

Example usage:

NumStacksPerGroup = 3;
NumGroupsPerAxis = 6;
NumStackElements = 4;

% labels to use on tick marks for groups
groupLabels = { 'Test'; 2; 4; 6; 8; -1; };
stackData = rand(NumGroupsPerAxis,NumStacksPerGroup,NumStackElements);

plotBarStackGroups(stackData, groupLabels);
set(gca,'FontSize',18)
set(gcf,'Position',[100 100 720 650])
grid on
set(gca,'Layer','top') % put grid lines on top of stacks

MATLAB Release Compatibility
Created with R2008b
Compatible with any release
Platform Compatibility
Windows macOS Linux
Acknowledgements

Inspired: Machine Learning with MATLAB

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!