Data labels above bars on grouped bar plot

155 ビュー (過去 30 日間)
Justin Solomon
Justin Solomon 2014 年 5 月 16 日
編集済み: dpb 2024 年 11 月 2 日 17:48
I'm making a grouped bar plot (i.e., a bar plot with multiple bars in each category). I would like to add labels at the top of each bar to indicate its height. I was planning to just use the text function. However, bars within a given group all have the same x location (i.e get(h,'XData') is the same for all bar series). I'm not sure how to find the proper x location for each bar within a given group. Any ideas?
Thanks, Justin
  3 件のコメント
dpb
dpb 2016 年 6 月 30 日
Submit the enhancement request to TMW @ www.mathworks.com
Benjamin Kraus
Benjamin Kraus 2024 年 11 月 1 日 0:09
At long last, bar labels are now built-in to MATLAB as of R2024b.
Check out the new example on the bar doc page: Create Bar Labels and the properties on the Bar object's property page.

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

採用された回答

dpb
dpb 2014 年 5 月 16 日
編集済み: dpb 2014 年 5 月 16 日
You're on the right track, the center of each group is at the axis tick value. For each bar in the group, use that value plus/minus a delta to locate the x position for your text.
I did an example of this for another poster within the last few weeks at most altho I don't have the link at hand. Perhaps a search will uncover it.
ADDENDUM:
OK, I looked at past answers--this one is pretty close altho I thought I did another. Maybe it was in the newsgroup instead...
  6 件のコメント
Mostafa Darvishi
Mostafa Darvishi 2016 年 10 月 3 日
Hello, I just tumbled into this post and I found it very interesting in my application. in this tripple bar plot, you used the array of [4 3] that means 4 intervals with 3 bars in each interval. But the function that you have used is a random number generator. My question is that how should I change the code in the case that I have 3 arrays as functions. For example I have three following arrays and I want to plot them in triple plot.
Y1 = [1 3 6 7 9 12 11]; Y2 = [12 5 8 13 11 1 4]; Y3 = [11 31 16 17 7 113 15];
dpb
dpb 2016 年 10 月 3 日
Just past 'em together...
Y=[Y1;Y2;Y3].'; % create nx3 column array for *bar*
NB: The latest release of bar uses HG2 and returns a handle to a barobject, rather than the former bar series objects. This new object is essentially opaque to the the details and the data for the patches used to draw the bars isn't available from which to compute the individual bar positions so labelling bars as this example does won't work. I've not got a more recent version so not sure what the workaround is, if there is one or if one must resort back to the earlier "trick" I illustrated before.

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

その他の回答 (6 件)

Benjamin Kraus
Benjamin Kraus 2024 年 11 月 1 日 0:22
With the release of MATLAB R2024b, this has gotten much easier.
Starting in MATLAB R2024b, Bar objects now have a Labels property that can be used to add labels to the tops of your bars. You can read about the new properties on the Bar objects property page.
For example:
b = bar(magic(3));
b(1).Labels = ["a","b","c"];
b(2).Labels = ["d","e","f"];
b(3).Labels = ["g","h","i"];
Solution for MATLAB R2019b through R2024a
If you can't upgrade to MATLAB R2024b just yet, you can still do this with a bit more work by using XEndPoints and YEndPoints properties that were added in R2019b.
b = bar(magic(3));
text([b.XEndPoints], [b.YEndPoints], ["a","b","c","d","e","f","g","h","i"], ...
VerticalAlignment='bottom', HorizontalAlignment='center')
  9 件のコメント
Steven Lord
Steven Lord 2024 年 11 月 2 日 15:23
I suppose trying having 'left', 'right' when is horizontal instead of 'top','bottom' when vertical would also add excessive cumbersomness to the UI, too, granted...although that would be the way to express.
Funny that you ordered them that way. I caught myself doing that as well when typing a first draft of that comment. Most of the time (when the data was positive) the 'left' label position for a horizontal bar would be the equivalent of the 'bottom' label position for a vertical bar rather than 'top'.
Naming things in a software design often can be easy in one (admittedly probably the most common) case for the designed functionality, but one of the challenges of designing/naming things (functions/methods, classes, properties, etc.) is to make the designs/names understandable, discoverable, and more-or-less accurate (or at least not misleading) in the general case. If I asked you to guess what percentage of the time I've spent in design reviews in have been spent arguing over and/or brainstorming names to generalize them, make them discoverable, and to help users be able to understand their purpose successfully, I'm almost certain you'd guess low.
And sometimes we can't really agree: we spent a lot of time brainstorming other names for Binary Single eXpansion FUNction aka bsxfun.
dpb
dpb 2024 年 11 月 2 日 15:52
編集済み: dpb 2024 年 11 月 2 日 17:48
I really didn't intend that left,right match top,bottom in the orderwhen posting that, I was just listing the alternative names that were the directional equivalents when horizontal instead of vertical. But, you are correct in that with "normal" positive values and increasing axis values to the right, the baseline would be 'left', and the magnigude to the 'right', instead. As you note, when one gets away from the plain vanilla, it does get complicated to define all the cases unambiguously in a manner that is consistent across all possibilities.
While it's not important to go into reasons why here, I was surprised by the comment that finding the center or other fractional height position so that an arbitrary (percentage say) position along the bar length turned out to be difficult to implement. Then again, I haven't thought in serious depth, so there's probably something obvious I'm overlooking there.
Oh, I can imagine indeed, that is is a very high fraction, indeed, as compared to the base functionality.
As for things like bsxfun, at least it didn't end up with a camel-cased 20-character long moniker! :)
ADDENDUM: Would 'base' and 'head' be orientation agnostic names, maybe???

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


Will Adler
Will Adler 2014 年 11 月 18 日
This doesn't work in R2014b any more, due to this.
The available bar series properties no longer have the info for the location of the bar. Any idea how to recreate this in grouped bar plots?
  8 件のコメント
dpb
dpb 2016 年 9 月 21 日
What's the issue, specifically? The x-position for the text object to write is given by the above; simply modify the y-position to place where wanted in the bar instead above it--the y distances are computable directly from the data; don't need similar machinations as do for x.
I was thinking I'd seen additional properties mentioned that were useful having been introduced in HG2 but a search the other day didn't seem to find such, unfortunately, so guess I had mixed up with something else.
Kelly Kearney
Kelly Kearney 2016 年 9 月 21 日
Moving the labels inside the bars is a simple matter of changing the horizontal alignment so the right edge, rather than left, aligns with the bar height (and in most cases, adding a small offset to the y-position so the text doesn't sit flush to the bar edge).
This example also assumes that your bars are all large enough to fit the full text string.
Y=random('unif',30,100,[4 3]); % sample data
h=bar(Y);
yb = cat(1, h.YData);
xb = bsxfun(@plus, h(1).XData, [h.XOffset]');
hold on;
padval = 1;
htxt = text(xb(:),yb(:)-padval, cellstr(num2str(yb(:))), ...
'rotation', 90, 'horiz', 'right');
set(htxt(1:3:end), 'color', 'w'); % for legibility

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


Image Analyst
Image Analyst 2014 年 5 月 17 日
For what it's worth, see attached demo. Adapt as needed.
  1 件のコメント
Justin Solomon
Justin Solomon 2014 年 5 月 17 日
Thanks for your comments. The difference in the case you show here and my case is that your bars are all centered on the ticks. If you have bar groups, then you have multiple bars grouped about the same xtick (see the image link in my original post). The only way I was able to figure out the exact center location of the each bar within a group was to get info from the underlying patch objects that are created when bar() is called. See my code above for an example.

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


aliyar attaran
aliyar attaran 2016 年 11 月 4 日
for 2 bars one one y value:
for i2=1:numel(y)
tx(i2,1)=text(x(i2),y(i2,1),num2str(y(i2,1),'%0.2f'),...
'HorizontalAlignment','right',...
'VerticalAlignment','bottom');
tx(i2,2)=text(x(i2),y(i2,2),num2str(y(i2,2),'%0.2f'),...
'HorizontalAlignment','left',...
'VerticalAlignment','bottom');
end

Elimelech Schreiber
Elimelech Schreiber 2017 年 11 月 5 日
I've written a function to do just this. It's called barvalues, and is very easy yo use.
simply:
bar(x);
barvalues;
  3 件のコメント
dpb
dpb 2017 年 11 月 6 日
編集済み: dpb 2017 年 11 月 6 日
I munged on your function some...haven't tested it thoroughly but it now works for the above case...haven't tried for more exotic examples. I know it won't work correctly for 'stacked' as the YData property isn't correct y location for it--not sure if it is retrievable or must be recomputed.
Modifications include
  1. fixing up isaType to look at all objects in handle array rather than just one (this may be too simplistic in some cases, I don't know; didn't study the search logic enough to know if could possibly pass a group that might be other than bar handles)
  2. using only one of the array handles in axes call to get axes handle (this could also possibly(?) be too simplistic if there are multiple bar objects but in multiple axes on a given figure), and
  3. looping over the handle array and adding the .XOffSet property differential to the text call.
Doesn't seem an easy way to add updates at the Exchange so I'll just paste the modified routine here for your convenience...
Giuseppe Naselli
Giuseppe Naselli 2022 年 7 月 15 日
Thanks for the barvalues function Elimelech, very easy to use and solid
Very appreciated
G

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


Halina H
Halina H 2017 年 12 月 7 日
Hi , I would like to know how to code to get the total value of each bar in this grouped bar graph ie , total bincounts for the yellow bar, total bincounts for blue bar , and total bincounts for green bar. I am interested to know which of these 3 bars give the most information
  1 件のコメント
Image Analyst
Image Analyst 2022 年 7 月 15 日
Since you plotted the 3 sets of data, you already have the counts. If you want the total number of counts, that's simply the number of elements in the data that you took the histogram of.

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

カテゴリ

Help Center および File ExchangeData Distribution Plots についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by