Put Y-Ticks above bars in stacked horizontal bar chart

7 ビュー (過去 30 日間)
AEdel
AEdel 2024 年 2 月 15 日
コメント済み: Adam Danz 2024 年 2 月 18 日
Hello everyone,
I am trying to make a stacked horizontal bar chart. As my y-ticks are rather long strings, I would like to place them above the respective bars. I tried it with the annotation function, but did not succeed. Where am i going wrong? Or is there another way of doing this?
I also want the bars to display the values of each bar (that I have managed)
y = [30 70; 20 80; 60 40];
b = barh(y, 'stacked','BarWidth',0.3);
% set y-axis tick labels
yticks(1:size(y, 1));
yticklabels({'Some very long question', 'Some more text', 'Even more text'})
% adjust tick label position
yPos = 1:size(y, 1);
barValues = sum(y, 2);
for i = 1:length(yPos)
annotation('textbox', [barValues(i) yPos(i)-0.2 0 0], 'String', num2str(barValues(i)),'VerticalAlignment', 'middle', 'HorizontalAlignment', 'left', 'FontSize', 10)
end
% insert values into each bar
for i=1:length(b)
for j = 1:length(b(i).YData)
y = b(i).YEndPoints(j) - (b(i).YData(j)) / 2;
s = sprintf('%.0f', b(i).YData(j));
text(y', b(i).XData(j), s);
end
end
% adjust other properties
title('The distribution of answers to each question');
legend('percentage of answer A', 'percentage of answer B');
Thank you for helping me out.

採用された回答

Austin M. Weber
Austin M. Weber 2024 年 2 月 16 日
編集済み: Austin M. Weber 2024 年 2 月 16 日
One option would be to use the text function:
y = [30 70; 20 80; 60 40];
b = barh(y, 'stacked','BarWidth',0.3);
labels = {'Some very long question', 'Some more text', 'Even more text'};
% Add labels above the bars
hold on
text(50, 1.25, labels(1),'HorizontalAlignment','center')
text(50, 2.25, labels(2),'HorizontalAlignment','center')
text(50, 3.25, labels(3),'HorizontalAlignment','center')
hold off
set(gca,'YTick',[]) % Get rid of exterior ytick marks
  1 件のコメント
AEdel
AEdel 2024 年 2 月 17 日
Thanks, this worked for me.

サインインしてコメントする。

その他の回答 (1 件)

Adam Danz
Adam Danz 2024 年 2 月 16 日
編集済み: Adam Danz 2024 年 2 月 16 日
Annotations are tricky because they rely on coordinates that are normalized to the figure area rather than using data units.
If you're adding text at specific locations in axes, use text.
This solution also vectorizes the bar labels instead of using a loop.
y = [30 70; 20 80; 60 40];
b = barh(y, 'stacked','BarWidth',0.3);
xStr = vertcat(b.XData)';
yStr = vertcat(b.YEndPoints)' - y/2;
str = string(y);
text(yStr(:),xStr(:),str(:),...
'HorizontalAlignment','Center',...
'VerticalAlignment','Middle', ...
'Color','w')
ylabs = {'Some very long question', 'Some more text', 'Even more text'};
ylabPos = b(1).XData + b(1).BarWidth/2;
xlabPos = b(1).BaseValue .* ones(size(ylabPos));
text(xlabPos, ylabPos, ylabs, ...
'HorizontalAlignment','left', ...
'VerticalAlignment','bottom')
yticklabels([])
  3 件のコメント
Austin M. Weber
Austin M. Weber 2024 年 2 月 18 日
Great question! Programmatically speaking, I would say that Adam's solution is superior because it can be easily applied to charts that have many data bars.
But, if you are creating a bar plot with only 3 bars, my solution takes fewer lines of code and may be easier to read for those who are less experienced with MATLAB syntax.
If you want to plot more than three bars using my solution, you would likely want to wrap the text function in a for-loop. Vectorizing your code (as Adam's solution demonstrates) is technically faster than a for-loop, but for simple plots like this you can decide whether you prefer the simpler solution or the optimized one. Both will work just fine.
Adam Danz
Adam Danz 2024 年 2 月 18 日
@AEdel It's great that you're engaging with different solutions and considering the options. Both approaches have their merits..
Regarding my solution, I've leveraged some of the bar properties to generalize the solution. For example, the vertical position of the text is computed using the XData and BarWidth properties instead of hard-coding the vertical position. This way, the solution can be applied to other bar charts that may have different bar widths. The horizontal position of the text is based on the BaseValue value which defines where the bars 'start'.
That said, it's always encouraging to see diverse approaches.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeAnnotations についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by