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:
I would like to remove x and y-axis from bar graph in Matlab, but x-axis is still visible and I can't find the reason why.
x = [1 2 3 4 5];
b = bar(x);
axis off
This is actually the 'baseline' of the bar() function.
Use set(b,'ShowBaseLine','off'); to turn it off.
I create a figure containing 4 subplots like:
y = [2 2 3; 2 5 6; 2 8 9; 2 11 12];
fig = figure
for i = 1 : 4
h(i) = subplot(1,4,i)
bar(y)
end
Now I would like to exchange the order of the subplots. For example the first subplot should go in the last column (4th) and the 2nd subplot should exchange with the 3rd.
Is it doable without generating again the figure?
Perhaps you could change their 'position' of the axes h. For instance:
% get position
pos = get(h,'position');
% change position, 1st <-> 4th, 2nd <->3rd.
set(h(1),'position',pos{4});
set(h(4),'position',pos{1});
set(h(2),'position',pos{3});
set(h(3),'position',pos{2});
There is a possibility which kind of regenerates the figure. You can go to the plot tools, right click the figure and select "Show code". This will open a new file with a function that recreates the figure. There you can change your subplot-position and call the function in order to obtain the figure with switched subplots.
While this recreates the figure, you do not have to re-evaluate the function or script that originally created the figure.
PS: I'm not sure how new this feature is.
In addition to swapping the Position property of the axes objects, you could also swap the Parent property of the bar objects. This has the advantage of leaving your axes positioning intact.
A simple example:
function testcode
y1 = [2 2 3; 2 5 6; 2 8 9; 2 11 12];
y2 = -y1;
h(1) = subplot(1, 2, 1);
b(1,:) = bar(y1);
h(2) = subplot(1, 2, 2);
b(2,:) = bar(y2);
swapbar(h, b, [1,2]);
end
function swapbar(axesobjects, barobjects, axesswap)
set(barobjects(axesswap(1), :), 'Parent', axesobjects(axesswap(2)));
set(barobjects(axesswap(2), :), 'Parent', axesobjects(axesswap(1)));
end
Here I've created a small helper function swapbar to swap two axes. This isn't at all a robust implementation but it works well to illustrate the concept.
Old:
New:
I have a set of values and a bunch of corresponding colours. The colours are dependent on the x labels but they are already in the correct order. How do I plot the bar chart such that the colours correspond to the correct bars. For example...
y= [2 4 12 7 15]'
bar_colour={'b';'b';'g';'r';'k'}
hp=bar(y,bar_colour{:})
At the moment, all the bars are in one colour.
In this case I think a loop is justified:
y = [2 4 12 7 15]'; %'
bar_colour = {'b';'b';'g';'r';'k'};
hold on
for n = 1:numel(y)
bar(n, y(n),bar_colour{n});
end
How can I add the infinity symbol to X axis of Matlab Bar graph?
Naturally it is possible to insert the infinity symbol i.e. '\infty' for xlabel, as seen in the last line of the inserted code.
But, I want to add the infinity sign in the x axis bar not in the x axis label.
How can I do that?
For the sake of detailed clarification, the following script is added bellow:
data=[1 2 3; 1 3 4; 3 1 2];
bar(data)
set(gca,'YLim',[0 3])
set(gca,'YTick',[0:0.5:3])
set(gca, 'YTickLabel',num2str(get(gca,'YTick')','%02.1f%%'))
set(gca,'Xtick',1:3,'XTickLabel',{'\infty' ; '20 dB'; '15 dB'})
xlabel('\infty dB') % x-axis label
How about this solution, using format_tick function from File Exchange?:
data=[1 2 3; 1 3 4; 3 1 2];
bar(data)
set(gca,'YLim',[0 3])
set(gca,'YTick',[0:0.5:3])
set(gca, 'YTickLabel',num2str(get(gca,'YTick')','%02.1f%%'))
set(gca,'Xtick',1:3)
format_ticks(gca, {'$\infty$' ; '20 dB'; '15 dB'})
I left out the xlabel because it interfers with the Xtick, but probably that can be easily moved to lower position.
EDIT:
To fix the overlap of Xtick and xlabel add this to the end of the code:
xlabh = get(gca,'XLabel');
set(xlabh,'Position',get(xlabh,'Position') - [0 .1 0])