Data not plotting as a 'stacked' bar chart?

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

 采纳的回答

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 个评论

That's interesting Cris, but the example won't lead anybody to figuring out that only using a single x value will cause the intended result. The 'style' argument says specifically
'stacked'
Display each group as one multicolored bar. The length of a bar is the sum of the elements in the group.
If y is a vector, then the result is the same as 'grouped'.
It says nothing about "except if x is a scalar, then the above doesn't apply and, in fact, 'stacked' does mean what it says it does". That is a serious shortcoming in the documentation and the examples; I've railed about this for 20+ years and this is first time I've seen it and, given the behavior, had no klew to even try such a thing.
Why it still should be needed to "fool Mother Bar" is beyond my ken; if it can do it with a scalar x, then why can't it do it when x is empty?
OBTW, good catch on using groupsummary, I just followed OP's example blindly in that regards, didn't even cross my mind...
At least thru R2020b, bar is an m-file and can see what it does...interesting that it's one of those that still has Cleve's footprint in original code... :)
Anyways, I found where it does the dirty deed if there is no x and blindly turns the input row vector into a column vector and goes on from there, subsequently ignoring the 'stacked' parameter it has carefully parsed...
It's easy to fix/patch if there are only the two arguments of (y,'stacked') form; unfortunately, the way the input code is structured it's not so simple when other input arguments may also be present. Obviously it could be done and I'd argue should be; but there are undoubtedly bigger fish to fry to get this to the top of the enhancement stack.
Ergo, I'd settle for a clear exposition in the documentation and examples to emphasize the need to specify x variable for the one bar case.
@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...

请先登录,再进行评论。

更多回答(1 个)

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

类别

帮助中心File Exchange 中查找有关 Interactive Control and Callbacks 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by