Search code examples
matlabplotmatlab-figure

Bar plot x-axis Matlab


I am stuck with a bar plot in Matlab. I got it to work with Matlab help and this this forum until here, but on the x-axis, there are still only 2 names. I would like to have the "names" under the bars and the "categories" where the 2 names show up now. Thank you!

values = [4 10...
    11 2 3;...
    4 1...
    5 2 -10];
names = {'PreSplitTotalEON' 'PostSplitTotalEON'...
    'PreSplitPureEON' 'PostSplitPureEON' 'PostSplitUniper';...
    'PreSplitTotalRWE' 'PostSplitTotalRWE'...
    'PreSplitPureRWE' 'PostSplitPureRWE' 'PostSplitInnogy'};
categories = {'EON', 'RWE'};
b = bar(values,'FaceColor','flat');
xticklabels([names(1,:)';names(2,:)'])         
% This will set labels to be used for each tick of the x-axis
xticks(1:1:length([names(1,:)';names(2,:)']))
% This will set how many ticks you want on the x-axis. Here, there
% should be 48 ticks being generated. One for each piece of data you have.
xtickangle(90)
% This will rotate the label so that the labels will not overlap
% with one another. This is in degrees.
for k = 1:size(values,2) % for fancier colors.
    b(k).CData = k;
end

Solution

  • The default way would be to use legend to display the name of each element in the group. But the position of each bar can be accessed through the XOffset and XData properties. See this answer in matlab central.

    So you can use something like:

    ticksList = b(1).XData+arrayfun(@(x)x.XOffset, b)';
    xticks(ticksList(:))
    xticklabels([names(1,:)';names(2,:)'])
    

    to correctly display the names below each bar. However, I don't see how you want to display the names of each bar and the categories together below the bars without overlapping. You could instead display the categories on top by creating a new axes. Adding Something like:

    ax1 = gca;
    ax2 = axes('Position', get(ax1, 'Position'),'Color', 'none');
    set(ax2, 'XAxisLocation', 'top','YAxisLocation','Right');
    set(ax2, 'XLim', get(ax1, 'XLim'),'YLim', get(ax1, 'YLim'));
    xticks(b(1).XData)
    xticklabels(categories)
    

    I.e. the complete code would be now:

    clear all
    close all
    
    values = [4 1 11 2 3; 4 1 5 2 -10];
    names = {'Pre split total EON' 'Post split total EON'...
        'Pre split pure EON' 'Post split pure EON' 'Post split Uniper';...
        'Pre split total RWE' 'Post split total RWE'...
        'Pre split pure RWE' 'Post split pure RWE' 'PostSplitInnogy'};
    categories = {'EON','RWE'};
    figure;
    b = bar(values,'FaceColor','flat');
    ticksList = b(1).XData+arrayfun(@(x)x.XOffset, b)';
    xticks(ticksList(:))
    xticklabels([names(1,:)';names(2,:)'])
    xtickangle(90)
    ax1 = gca;
    ax2 = axes('Position', get(ax1, 'Position'),'Color', 'none');
    set(ax2, 'XAxisLocation', 'top','YAxisLocation','Right');
    set(ax2, 'XLim', get(ax1, 'XLim'),'YLim', get(ax1, 'YLim'));
    set(ax2, 'YTick', []);
    xticks(b(1).XData)
    xticklabels(categories)
    for k = 1:size(values,2) % for fancier colors.
        b(k).CData = k;
    end
    

    Figure output