Put Y-Ticks above bars in stacked horizontal bar chart
6 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
AEdel
am 15 Feb. 2024
Kommentiert: Adam Danz
am 18 Feb. 2024
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.
0 Kommentare
Akzeptierte Antwort
Austin M. Weber
am 16 Feb. 2024
Bearbeitet: Austin M. Weber
am 16 Feb. 2024
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
Weitere Antworten (1)
Adam Danz
am 16 Feb. 2024
Bearbeitet: Adam Danz
am 16 Feb. 2024
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([])
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1619608/image.png)
3 Kommentare
Austin M. Weber
am 18 Feb. 2024
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
am 18 Feb. 2024
@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.
Siehe auch
Kategorien
Mehr zu Annotations finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!