MATLAB Answers

How do i label each bar in bar group with a "string" on top?

453 views (last 30 days)
ammara khurshid
ammara khurshid on 1 Oct 2017
Commented: Rahim Rahim on 23 Apr 2021
Hi ! Urgent help needed. I have a grouped bar graph and i want to add text on the top of each bar in each group. I am doing this way:
y = [58.1395 62.7907; 40.3900 40.3400]
Y=bar(y)
str={'John'; 'Adam'};
set(gca, 'XTickLabel',str, 'XTick',1:numel(str))
labels= {'Physics', 'Chemistry'; 'Physics', 'Chemistry'};
xt = get(gca, 'XTick');
text(xt, y, labels, 'HorizontalAlignment','center', 'VerticalAlignment','bottom')
Am getting error "error using text Value must be a column or row vector in bar plot" and not able to fix it. Am working in R2015b. Help me.

Accepted Answer

dpb
dpb on 1 Oct 2017
Edited: dpb on 12 Dec 2019
...
hB=bar(y); % use a meaningful variable for a handle array...
hAx=gca; % get a variable for the current axes handle
hAx.XTickLabel=str; % label the ticks
hT=[]; % placeholder for text object handles
for i=1:length(hB) % iterate over number of bar objects
hT=[hT text(hB(i).XData+hB(i).XOffset,hB(i).YData,num2str(hB(i).YData.','%.3f'), ...
'VerticalAlignment','bottom','horizontalalign','center')];
end
The text command does the two groups with the two bars of each group labeled in the one call for each bar group. The x position is that of the data plus the offset and the y position is the data value. The label is formatted to string to be written by num2str; note carefully the transpose operator .' to create a column vector; this is imperative or the two values would be strung together on a single line.
The "trick" is in the hB.XOffset term; the 'XOffset' property is hidden so have to know it exists a priori as there's nothing to give away its existence nor any other data available from which to compute the dX that the routine uses internally for the offset of the bar center from the x location of the group. As noted above, this is a real foopah on TMW's part...
The above results in
ADDENDUM
Specifically addressing the concern that didn't do the labels,
hT=[]; % placeholder for text object handles
for i=1:length(hB) % iterate over number of bar objects
hT=[hT,text(hB(i).XData+hB(i).XOffset,hB(i).YData,labels(:,i), ...
'VerticalAlignment','bottom','horizontalalign','center')];
end
results in
instead...
  4 Comments
dpb
dpb on 2 Oct 2017
No problem...glad to help. Note the error originally about a vector as input for text had to do with how you referenced the labels array without any subscripting which is 2D instead of 1D vector.
The suggested correction of using (:) to cast to the column vector would have fixed that error but you'd have found that you'd written both sets of labels at the same x locations and that would have been at the midpoint between the actual bars, not on the bars themselves. That's one of the "bones of discontent" I have and have had w/ TMW on bar as a general function for years that it just isn't nearly as well-designed as it could/should be.

Sign in to comment.

More Answers (3)

Ben Oeveren
Ben Oeveren on 12 Sep 2018
Edited: dpb on 12 Sep 2018
For those still searching for a solution. Based on previous comments I've used this:
y = grpstats(x,grps,'sum');
ytxt = round(y./repmat(nansum(y,2),1,size(y,2))*100);
ytxt = num2cell(ytxt);
ytxt = cellfun(@(x) [sprintf('%0.1f',x), '%'], ytxt,'un',0);
figure('Position',[107 516 813 182]);
hB = bar(y,'group','EdgeColor','w','BarWidth',1);
hT=[]; % placeholder for text object handles
for i=1:length(hB) % iterate over number of bar objects
hT=[hT,text(hB(i).XData+hB(i).XOffset,hB(i).YData, ytxt(:,i), ...
'VerticalAlignment','bottom','horizontalalign','center')];
end
grid on
  1 Comment
dpb
dpb on 12 Sep 2018
NB: Can write the code to produce the strings from the numeric values a little more simply -- don't need to cast to cell array first:
ytxt=cellstr(num2str(ytxt(:),'%0.1f%%'));

Sign in to comment.


Image Analyst
Image Analyst on 1 Oct 2017
You can use text() to put text atop each bar. Attached is a demo/example.
  4 Comments
dpb
dpb on 2 Oct 2017
And to amplify further, im(nsh)o < :) >, bar series should have builtin property of label for each bar similar to an axes object 'X|Y|ZTickLabel' with associated properties for positioning it in|outside the bar, horizontal|vertical, etc., etc., etc., ... If just boggles the mind the number of hours folks have spent cumulatively over the years dealing with such trivia instead of actually solving the underlying problem they're working on.

Sign in to comment.


Mohammed Abdallatif
Mohammed Abdallatif on 6 Nov 2019
Can someone help to locate the Description (Labels) in the middle of each section of the bar instead of the top? I must change the Y-coordinate of the text, but it needs to be automatically centered and I don't know how.
Code:
text(b(i).XData(n), b(i).get.YEndPoints(n),Labels(n,counter),'HorizontalAlignment','center',...
'VerticalAlignment','bottom');
Unbenannt.png
  3 Comments

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!