I have a tricky question, which I think cannot be simply answered.
I have a large data table and want to save bar charts for each 2 corresponding mean values. I already did that with "for loop", but I cannot set different colors to my bars and cannot set proper spaces between bars and axes.
That's the simplest example:
k = [2 5]
bar(k)
Matlab thinks about those data [2 5] as about one "group" and it does not give a possibility of changing color for only one bar.
Of course, when we have different "groups", colors are changeable.
y = bar([1 2 3; 4 5 6]);
y(2).FaceColor = 'red';
But what about my example? I need only two bars, and I need to color them differently. Also, I want to set a small space between each bar and the axes (and again with two bars it is not that simple, and I cannot use "bar width" because that doesn't give me what I really want).
Does anyone know how to get around this?
Thanks for any reply! Mary
A good trick could be add zero column for each group:
k = [2 5;0 0];
bar(k,'grouped')
UPDATE
Another solution to have different color could be using location in bar
:
k = [2 5];
figure(1);
hold on;
h=bar(1,k(1));
set(h,'FaceColor','k');
h=bar(2,k(2));
set(h,'FaceColor','b');
hold off
As far as I know, this requires the use of a custom bar plot, since Matlab's barplots use dynamic colormaps. Personally, I like the GRAMM toolbox for all these customizations: [GRAMM on file-exchange] [GRAMM on github].
Here's an example:
x = [1 2];
y = [1 1.5];
c = x;
custom_map = ...
[1 0.3673 0.4132;
0 0.7375 0.8344];
clear g
g(1,1)=gramm('x',x,'y',y,'color',c);
g(1,1).geom_bar('width',0.2);
g(1,1).set_title('Width = 0.2');
g(1,2)=gramm('x',x,'y',y,'color',c);
g(1,2).geom_bar('width',0.8);
g(1,2).set_title('Width = 0.8');
g.set_names('y','','x','');
g.set_color_options('map',custom_map);
g.axe_property('YTick',[],'LineWidth',1,'YColor',[1 1 1],'XLim',[0.5 2.5],'XTick',[1 2])
figure('Position',[100 100 600 300]);
g.draw();
The histogram
function is one option that will easily handle the spacing and x-axis labeling, but you'll have to plot each bar separately to independently control the colors:
k = [2 5];
histogram('Categories', {'ONE'}, 'BinCounts', k(1), 'BarWidth', 0.8, ...
'FaceAlpha', 1, 'FaceColor', [0 0.4470 0.7410]);
hold on;
histogram('Categories', {'TWO'}, 'BinCounts', k(2), 'BarWidth', 0.8, ...
'FaceAlpha', 1, 'FaceColor', [0.8500 0.3250 0.0980]);
Here is an option to workaround this. You can use diag(k)
to create a 2*2 matrix with all zeros except the main diagonal that will be with your values, and Matlab will read it as 2 different groups. Then you change the Xdata
of the 'dummy' bars (which you don't see but take some space on the x axis to nan
so Matlab will ignore it.
k = [2 5];
b = bar(diag(k));
set(b,{'XData'},{[1 nan],[nan 1]}); % remove the group you don't want
set(gca,{'xticklabel','XTick'},{{'ONE','TWO'},[0.85 1.15]});
b(2).FaceColor = 'r'; % choose a different color
The result:
And if you want to generalize this to more groups (here it's 5):
k = 1:5;
data = diag(k);
xdata = eye(numel(k))./eye(numel(k)); % a martix of nan with 1 on the main diagonal
b = bar(diag(k));
% remove all data except one bin in all groups:
set(b,{'XData'},mat2cell(xdata,ones(size(data,1),1),size(data,2)))
X = xlim; 5 get x-axis limits
w = (1-X(1))/(numel(k)/2); % calculate the width of one bin
set(gca,'XTick',X(1)+w/2:w:X(2)) % set the X ticks to the center of the bins
set(gca,'xticklabel',{'ONE','TWO','THREE','FOUR','FIVE'}); % set the labels
set(b,{'FaceColor'},mat2cell(lines(numel(k)),ones(size(data,1),1),3)); % set the colors
and you get:
And finally, if you want them to 'hover' a little above the x-axis, you can add the following lines:
b(1).BaseLine.Color = 'none'; % remove the base line
ylim([-0.1 max(k(:))]) % shift the bars up a little
and get:
来源:https://stackoverflow.com/questions/45568120/matlab-bars-changing-the-color-of-the-bar-and-the-space-between-bars-and-axes