Search code examples
matlabplotbar-chartmatlab-figure

Labels above grouped bar chart


Problem

I am generating a bar chart and would like to display the height of each bar above the bar itself (Ydata). So for the following picture which is an example, I would like to have labels above the charts. I couldnt find a solution to this. For your information I am using Matlab R2016a.

enter image description here

Code

Currently I am using the following code to create my chart.

   x={ '-5-0' '0-5' '5-10' '10-15' '15-20' '20-25' '25-30' '30-35' '35-40' '40-45' '45-50' '50-55'};
before= [0 27 28 18 9 6 5 3 2 1 1 0]
after= [27 28 18 9 6 5 3 2 1 1 0 0]
y=[before',after']

h=figure;
hold on
yyaxis left
l1=bar([1:12],y,'grouped');

hYLabel=ylabel('Tonnage [%]');
yyaxis right
hylabel=ylabel('Tonnage [%]');
l1(1).FaceColor = [ 0    0.447  0.7410];
l1(1).EdgeColor = [ 0    0.447  0.7410];
l1(2).FaceColor =[0.85 0.325 0.098]
l1(2).EdgeColor =[0.85 0.325 0.098]
hTitle=title('Test');
hXLabel = xlabel('Value [$/t]');
hLegend=legend([l1(1),l1(2)], 'Test1', 'Test2');
set([gca,hTitle,hXLabel,hYLabel,hLegend] , 'FontName'   , 'Helvetica','FontSize', 8) 
set(hTitle,'FontSize', 11) 
set(hLegend,'Fontsize',8,'Location', 'southoutside', 'Orientation','horizontal')
set(gca,'XTick',[1:12])
xlim([0.5 12.5])
set(gca,'xticklabel',x.')
set(gca,'LineWidth',1.0)

hold off

What I am looking for Quick illustration of what I am looking for. Obviously I want a label above each column. Any help would be very appreciated.

enter image description here


Solution

  • After your line:

    l1=bar([1:12],y,'grouped');
    

    add following lines:

    x_shift = 0.15;
    text([1:12]-x_shift,y(:,1)+1,num2str(y(:,1)),...
        'FontSize',12,'HorizontalAlignment','Center','Color',[0 0.447  0.7410])
    text([1:12]+x_shift,y(:,2)+1,num2str(y(:,2)),...
        'FontSize',12,'HorizontalAlignment','Center','Color',[0.85 0.325 0.098])
    

    And you will get:

    Labeled bar

    if you want the percentage format, and also rotation, then the x_shift need to be adjusted a little bit more, and also the y-axis limits, so I bring here the full code for that:

    x={'-5-0' '0-5' '5-10' '10-15' '15-20' '20-25' '25-30' '30-35'...
        '35-40' '40-45' '45-50' '50-55'};
    before= [0 27 28 18 9 6 5 3 2 1 1 0];
    after= [27 28 18 9 6 5 3 2 1 1 0 0];
    y=[before',after'];
    ax = axes('xticklabel',x.','LineWidth',1.0,'XTick',1:12);
    yyaxis(ax,'left')
    l1 = bar(ax,y,'grouped');
    x1_shift = -0.17;
    x2_shift = 0.11;
    text([1:12]+x1_shift,y(:,1)+1,[num2str(y(:,1)) repmat('%',numel(y(:,1)),1)],...
        'FontSize',12,'Rotation',90,'HorizontalAlignment','left',...
        'VerticalAlignment','middle','Color',[0 0.447  0.7410])
    text([1:12]+x2_shift,y(:,2)+1,[num2str(y(:,2)) repmat('%',numel(y(:,2)),1)],...
        'FontSize',12,'Rotation',90,'HorizontalAlignment','left',...
        'VerticalAlignment','middle','Color',[0.85 0.325 0.098])
    ylabel('Tonnage [%]','FontName','Helvetica','FontSize',8);
    ylim([0 35])
    yyaxis(ax,'right')
    ylabel('Tonnage [%]','FontName','Helvetica','FontSize',8);
    l1(1).FaceColor = [0 0.447  0.7410];
    l1(1).EdgeColor = [0 0.447  0.7410];
    l1(2).FaceColor = [0.85 0.325 0.098];
    l1(2).EdgeColor = [0.85 0.325 0.098];
    title('Test','FontName','Helvetica','FontSize', 11);
    xlabel('Value [$/t]', 'FontName'   , 'Helvetica','FontSize', 8);
    hLegend = legend([l1(1),l1(2)], 'Test1', 'Test2');
    set(hLegend,'Location','southoutside','Orientation','horizontal',...
        'FontName', 'Helvetica','FontSize', 8)
    xlim([0.5 12.5])
    ylim([0 35])
    box off
    

    you will notice I changed your code a little, to make it more compact, but essentially it does the same, and yields the following bar:

     percentage format

    the labels here will be placed in the same position (relative to the bars) even if you resize the graph.