How to label the numeric values at the end of a stack in a stacked bar graph?
3 ビュー (過去 30 日間)
表示 古いコメント
Y1 = [1 2 0 4];
Y2 = [2 4 6 0];
Y = [Y1; Y2];
Bin = bar(Y,'stacked');
xt = get(gca, 'XTick');
set(gca, 'XTick', xt, 'XTickLabel', {'Trial 1' 'Trial 2'})
ybin = get(Bin,'YData');
ybinlabel = {'Standing','Walking','Jogging','Sprinting'};
barbase = cumsum([zeros(size(Y,1),1) Y(:,1:end-1)],2);
speedlblpos = Y/2 + barbase;
for k1 = 1:size(Y,1)
text(xt(k1)*ones(1,size(Y,2)), speedlblpos(k1,:), ybinlabel, 'HorizontalAlignment','center','FontSize',16)
end
xlabel({'Activity'},'FontWeight','bold');
ylabel({'Activity Distribution (%)'},'FontWeight','bold')

That is the code I have which labels the sections of the data. I want to know how to get the numerical value or percentage in this case, to be displayed at the top of the bar in the stacked graph. Also, I would like to find a way to silence the activity label on the data when it is not being performed during a trial.
採用された回答
Adam Danz
2023 年 1 月 31 日
編集済み: Adam Danz
2023 年 1 月 31 日
Here's a demo you can adapt to your needs.
I reworked a bit of your code to
- Use categorical x values instead of setting xtick and xticklabel
- Compute location of strings more efficiently
- Ignore segments with 0 height
- Add percentage of each segment within each stack.
Y1 = [1 2 0 4];
Y2 = [2 4 6 0];
Y = [Y1; Y2];
x = categorical({'Trial 1' 'Trial 2'});
Bin = bar(x,Y,'stacked');
ybinlabel = {'Standing','Walking','Jogging','Sprinting'};
ycs = cumsum(Y,2);
percentPerSegment = ycs./ycs(:,end)*100;
for k1 = 1:size(Y,2)
nonzero = Y(:,k1)>0;
str = compose('%s (%.1f%%)',ybinlabel{k1},percentPerSegment(:,k1));
text(x(nonzero), ycs(nonzero,k1), str(nonzero), ...
'HorizontalAlignment','center','VerticalAlignment','top','FontSize',10)
end
xlabel({'Activity'},'FontWeight','bold');
ylabel({'Activity Distribution (%)'},'FontWeight','bold')
If you want the percentage shown along the y-axis,
Y1 = [1 2 0 4];
Y2 = [2 4 6 0];
Y = [Y1; Y2];
x = categorical({'Trial 1' 'Trial 2'});
figure()
Bin = bar(x,Y,'stacked');
ybinlabel = {'Standing','Walking','Jogging','Sprinting'};
ycs = cumsum(Y,2);
for k1 = 1:size(Y,2)
nonzero = Y(:,k1)>0;
str = compose('%s (%.0f%%)',ybinlabel{k1},ycs(:,k1));
text(x(nonzero), ycs(nonzero,k1), str(nonzero), ...
'HorizontalAlignment','center','VerticalAlignment','top','FontSize',10)
end
xlabel({'Activity'},'FontWeight','bold');
ylabel({'Activity Distribution (%)'},'FontWeight','bold')
0 件のコメント
その他の回答 (2 件)
Voss
2023 年 1 月 31 日
Something like this?
Y1 = [1 2 0 4];
Y2 = [2 4 6 0];
Y = [Y1; Y2];
Bin = bar(Y,'stacked');
xt = get(gca, 'XTick');
set(gca, 'XTick', xt, 'XTickLabel', {'Trial 1' 'Trial 2'})
ybin = get(Bin,'YData');
ybinlabel = {'Standing','Walking','Jogging','Sprinting'};
barbase = cumsum([zeros(size(Y,1),1) Y(:,1:end-1)],2);
bartop = barbase+Y;
speedlblpos = Y/2 + barbase;
for k1 = 1:size(Y,1)
idx = Y(k1,:) > 0;
text(xt(k1)*ones(1,nnz(idx)), speedlblpos(k1,idx), ybinlabel(idx), 'HorizontalAlignment','center','FontSize',12)
text(xt(k1)*ones(1,nnz(idx)), bartop(k1,idx), string(Y(k1,idx)), 'VerticalAlignment','top', 'HorizontalAlignment','center','FontSize',12)
end
xlabel({'Activity'},'FontWeight','bold');
ylabel({'Activity Distribution (%)'},'FontWeight','bold')
4 件のコメント
the cyclist
2023 年 1 月 31 日
More of an editorial comment than just adding to the solid solutions that are already here, but I think a more economical (and more conventional) solution is to put the bar labels into a legend (which automatically solves your zeros issue).
Also, the infographic guru Edward Tufte would say that it is usually mistake to put the values on the bars. It is "chart clutter". If the consumer of the graphic actually needs to know the exact values, as opposed to the reading the values approximately off the chart, then a small table is very likely the better way to present the data. If you present all the data as text, what is the point of the chart? Ref: The Visual Display of Quantitative Information.
Y1 = [1 2 0 4];
Y2 = [2 4 6 0];
Y = [Y1; Y2];
figure
Bin = bar(Y,'stacked');
xt = get(gca, 'XTick');
set(gca, 'XTick', xt, 'XTickLabel', {'Trial 1' 'Trial 2'})
ybin = get(Bin,'YData');
ybinlabel = {'Standing','Walking','Jogging','Sprinting'};
barbase = cumsum([zeros(size(Y,1),1) Y(:,1:end-1)],2);
speedlblpos = Y/2 + barbase;
xlabel({'Activity'},'FontWeight','bold');
ylabel({'Activity Distribution (%)'},'FontWeight','bold')
legend(ybinlabel,'Location','NorthWest')
参考
カテゴリ
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!