How to label the numeric values at the end of a stack in a stacked bar graph?

조회 수: 2 (최근 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.
  댓글 수: 2
Adam Danz
Adam Danz 2023년 1월 31일
Are you asking how to add text to the top of each stacked bar (2 text objects) or how to add text to the top of each segement (6 text objects)?
Kendell
Kendell 2023년 1월 31일
Hi Adam, I am asking how to get the text for each top segment. So it would be 3 segments for each trial in this case so 6 text objects.

댓글을 달려면 로그인하십시오.

채택된 답변

Adam Danz
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
  1. Use categorical x values instead of setting xtick and xticklabel
  2. Compute location of strings more efficiently
  3. Ignore segments with 0 height
  4. 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')

추가 답변 (2개)

Voss
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
Kendell
Kendell 2023년 2월 16일
@Voss I have been running this code and when I copy and paste this code twice in a script, the number label at the top goes away. For example, I wanted to do percentage of time spent standing, walking, jogging, and running. That would run perfectly and output the label and the value at the top of the bar graph like you have shown. Now, within the same script I want to do a graph of the amount of time spent doing each activity. It will create the bar graph and labels, but it will not display the time value at the top of the bar graph. Is there any way you could help with that?
Voss
Voss 2023년 2월 16일
Please post your script and I'll take a look.

댓글을 달려면 로그인하십시오.


the cyclist
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')
  댓글 수: 2
Adam Danz
Adam Danz 2023년 1월 31일
@Kendell, consider @the cyclist's advice. You can easily adapt any of the answers here to add a legend like this to the percentage labels.
I usually giving users the benefit of doubt when answering questions in the forum by showing users how to do what they are asking to do rather than trying to change their minds. Often it is the case that the question is just a minimal example rather than the full story. But in this case, a legend is standard practice rather than group labels.
Kendell
Kendell 2023년 1월 31일
@Adam Danz & @the cyclist I agree. I also find that having a legend and not generating massive amounts of "chart clutter" to be more beneficial. Unfortunately this is how my assignment was requested to be done. Thank you kind folk for the assistance and for the advice. This is my second question on here and man you guys are fast. Thanks again!

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Annotations에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by