简体   繁体   中英

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

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)

Ie 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

图输出

  • You need to observe the x-axis from the graph, and approximate the start and end x-axis values of the bars.
  • On the inspection it was found that bars start from 0.54 (the gap) at the x-axis and ends near 2.32.
  • Next, divide the x-axis into 12 tick positions using the command xticks,
  • and then mark those position with the required labels using the command xticklabels. That's all.

The required code to do so is given below.

close all
clear all

values = [4 10 ...
    11 2 3; ...
    4 1 ...
    5 2 -10];

% just declare the names lables as a simple 1-D cell array
% remove the columns and construct as row wise cell array
names = {'PreSplitTotalEON','PostSplitTotalEON', ...
    'PreSplitPureEON', 'PostSplitPureEON', 'PostSplitUniper', ...
    'PreSplitTotalRWE', 'PostSplitTotalRWE', ...
    'PreSplitPureRWE', 'PostSplitPureRWE', 'PostSplitInnogy'};
% declare the categories label
categories = {'EON', 'RWE'};
% construct the bar
b = bar(values,'FaceColor','flat');

%-> mark the respective xticks <-
% on close inspepection, it was found that the bars starts
% near 0.54 and end at nearly 2.31 at the x-axis
% so divide the x axis in 12 ticks within those limits.
xticks([linspace(0.54, 2.31, 12)]);

% now put the lables at those limits, that all
xticklabels({categories{1}, names{1:5}, categories{2}, names{6:10}})

xtickangle(90)
% This will rotate the label so that the labels will not overlap
% with one another. This is in degrees.
for k = 1:5 % for fancier colors.
    b(k).CData = k;
end

Output 在此处输入图片说明

Here is a fix for your code to get the desired output (explenations inside):

values = [4 10 11 2 3;
          4 1 5 2 -10];
names = {'PreSplitTotal' 'PostSplitTotal'...
    'PreSplitPure' 'PostSplitPure' 'PostSplitUniper';...
    'PreSplitTotal' 'PostSplitTotal'...
    'PreSplitPure' 'PostSplitPure' 'PostSplitInnogy'}.'; % <-- note the transpose!
categories = {'EON', 'RWE'};
N_names = size(values,2);
ax = axes('NextPlot','add'); % <-- same as 'hold on'
col = lines(N_names); % choose your favorite colormap
% draw the bars in pairs by their 'names':
for k = 1:N_names % for fancier colors.categories
    b = bar(ax,[k k+N_names+1],values(:,k),0.15,...
        'FaceColor',col(k,:));
end
xticks([1:N_names (N_names+2:N_names*2+1)]) % does not crate a tick for the space between categories
xticklabels(names(:))
xtickangle(30)
% place the category name on top of the axes:
text(ceil(N_names/2)+[0 N_names+1],ax.YLim(2).*[1 1],categories,...
    'VerticalAlignment','bottom','HorizontalAlignment','center')

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM