Data not plotting as a 'stacked' bar chart?

22 views (last 30 days)
Hi,
I have an some data based on 18 "regions" e.g. Alaska, Central America, Europe etc... stored as a 18x1 categorical. In a separate 18x1 array, I have the counts of each of these regions (e.g. 25 for Europe, 12 for Alaska etc...), with 319 records in total. I also have a 319x1 categorical array of the full dataset of the categories.
I want to plot them as a 'stacked' bar chart, with one bar with all the 319 records, broken down by the region, although currently it plots them as 18 separate bars, regardless of if I use the 'stacked' argument or not. It seems like an easy fix but I've been stuck on it for a while. Any help is appreciated, my current code is below and I've attached the original data file.
Thanks!
clear all
close all
[num,txt,raw]=xlsread('DefCat_All_Erup.xlsx');
Region = raw(2:320,15);
Region = cellstr(Region);
figure(1)
Region=categorical(Region);
Regions_X = categories(Region);
Regions_X = categorical(cellstr(Regions_X));
Regions_Y = countcats(Region);
Regions_Y = Regions_Y.';
bar(Regions_X, Regions_Y,'stacked')
hold off

Accepted Answer

Cris LaPierre
Cris LaPierre on 13 Oct 2022
You are creating your bar plot with 18 differing X values, and a corresponding Y value for each. For a stacked plot, see this example.
When your input is a vector, MATLAB will still try to create a bar for each value. So in your case, you need to explicitly tell MATLAB you want a single bar by specifing one X value.
For your data, I would probably do something like this.
file = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/1154913/DefCat_All_Erup.xlsx';
data = readtable(file,'NumHeaderLines',0,'VariableNamingRule','preserve');
tbl = groupsummary(data,'Location')
tbl = 18×2 table
Location GroupCount __________________________________ __________ {'Africa and Red Sea' } 33 {'Alaska' } 58 {'Antarctica' } 1 {'Atlantic Ocean' } 12 {'Canada and Western USA' } 24 {'Hawaii and Pacific Ocean' } 7 {'Iceland and Arctic Ocean' } 23 {'Indonesia' } 6 {'Japan, Taiwan, Marianas' } 26 {'Kamchatka and Mainland Asia' } 10 {'Mediterranean and Western Asia'} 14 {'Melanesia and Australia' } 6 {'Middle East and Indian Ocean' } 4 {'México and Central America' } 14 {'New Zealand to Fiji' } 17 {'Philippines and SE Asia' } 5
bar(1,tbl.GroupCount,'stacked')
legend(tbl.Location,'Location','eastoutside')
  4 Comments
dpb
dpb on 17 Oct 2022
@Cris -- if folks follow to get to all the examples, that's great -- and having it is certainly better than not. :)
I'd still contend the doc 'style' description needs to also mention the condition under its description of 'stacked' that must use an x value for a single bar as well. It might also otta' be in x input description and/or one of the hints, maybe???
But, that's a sizable step forward and it is sorta' an edge case, but it does seem like I've answered the same problem in the distant past...

Sign in to comment.

More Answers (1)

dpb
dpb on 13 Oct 2022
Edited: dpb on 13 Oct 2022
bar is an abomination of an implementation -- it is documented that if the input data are a vector, the 'stacked' option is interpreted the same as if it were 'grouped' -- iow, the designers didn't consider it to be a needed option.
I don't recall if I've been able to mung on it to make it work or not; I've done a lot over the years and continue to harangue Mathworks about the shortcomings, but it's been an uphill struggle get any really significant changes...well, usual rant aside, let's see...
tD=readtable(websave('DefCat_All_Erup.xlsx','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1154913/DefCat_All_Erup.xlsx'));
tD=convertvars(tD,@iscellstr,'categorical');
tD.Properties.VariableNames(15)={'Region'};
regionCounts=countcats(tD.Region).';
% here's the trick -- add a second row of NaN values so bar has an in array
% instead of just a vector. That's enough to make it honor 'stacked' style
% and NaN values are never displayed so nothing unwanted actually shows up
bar([regionCounts;nan(size(regionCounts))],'stacked')
legend(categories(tD.Region),'location','eastoutside')
xticks([])
xlim([-0.2 2.2])
OK, you can fake it by introducing the second row of NaN and then futz around with the xlim values to center the bar.
You can experiment with changing the size of the box with the axes 'Position' property or turn the box off, etc., etc., ...
NOTA BENE: The "nan trick" is an exceedingly useful one with handle graphics in general to create desired effects -- unfortunately, it's rather esoteric and unfortunate have to resort to such artifices, but it is what it is...

Categories

Find more on Data Distribution Plots in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!