Multi Colors and Legend for each bar
Show older comments
How do I set Multi Colors and Legend for each bar? Here I have given below my code
clc;
close all;
clear;
y = [467000, 150777, 20915, 229073, 95844];
figure;
bar(y);
set(gca,'XTickLabel',{'DG', 'PV', 'Converter', 'Battery', 'Flywheel'})
xlabel ('Components','fontweight','bold','FontSize',15)
ylabel ('Net Present Cost($)','fontweight','bold','FontSize',15)
grid on

Accepted Answer
More Answers (1)
Colorbar option
barData = rand(1,5);
figure();
bh = bar(barData);
% set bar color
bh.FaceColor = 'flat';
bh.CData = jet(numel(barData)); % use any colormap you'd like
% Add colorbar with categorical color labels
colormap(bh.CData)
cb = colorbar();
caxis([0,numel(barData)])
cb.YTick = 0.5 : 1 : numel(barData);
cb.TickLabels = {'Plovdiv','Varna','Burgas','Ruse','Haskovo'};
cb.TickLabelInterpreter = 'none';
cb.FontSize = 8;
bh.Parent.Position(3) = 0.55; % make the axis narrower to fit the colorbar labels.
Legend option
You can create each bar separately and specify its x-values.
% barData = rand(1,5)
colors = jet(numel(barData));
names = {'Plovdiv','Varna','Burgas','Ruse','Haskovo'};
fig = figure();
ax = axes(fig);
hold(ax,'on')
h = gobjects(size(barData));
for i = 1:numel(barData)
h(i) = bar(ax, i, barData(i), ...
'FaceColor', colors(i,:), ...
'DisplayName', names{i});
end
legend(h,'location','bestoutside')
xlim(ax, [0.25, numel(barData)+0.75])
box(ax,'on')
3 Comments
@Adam Danz, if you're going to build the separate bars to create the handles anyway, why don't you just forego the first and build them to begin with?
figure
hB=gobjects(numel(barData),1);
dumData=nan(size(barData)); % a place holder won't display
x=1:numel(barData); % x values to draw full-sized bar
for i = 1:numel(barData)
dumData(i)=barData(i); % the fixup show only one bar at time
hB(i)=bar(x, dumData,'FaceColor',bh.CData(i,:)); % now can specify 'FaceColor'
if i==1, hold on, end % hold on first doesn't set overall x limits
dumData(i)=nan; % put the NaN back for next iteration
end
legend(TickLabels,'Location','northwest')
produces

This way, you can get the default color order automagically by simply leaving out the 'FaceColor' parameter or use the named color abbreviations or whatever choose...
This adds some complexity to build the dummy data array at the slight advantage of being able to set 'FaceColor' instead of futzing with the internal CData array or the one-handle object. It's that extra effort that made me use the area subterfuge to get a set of handles drawn with patches that could do in "one swell foop" instead.
I STILL say any/all of these machinations are reflections on the ill-chosen design and UI for bar() itself that should directly addressable properties for every bar, property fields for applying labels, the values and so on directly.
You don't even need the padding. I'll update my answer since this is better than my second option.
y = [2 4 3 5 2]; % bar heights
colors = lines(numel(y));
names = {'Plovdiv','Varna','Burgas','Ruse','Haskovo'};
fig = figure();
ax = axes(fig);
hold(ax,'on')
h = gobjects(size(y));
for i = 1:numel(y)
h(i) = bar(ax, i, y(i), ...
'FaceColor', colors(i,:), ...
'DisplayName', names{i});
end
legend(h,'location','bestoutside')
xlim(ax, [0.25, numel(y)+0.75])
"You don't even need the padding."
But then you must manually fix up the axes limits as
xlim(ax, [0.25, numel(y)+0.75])
which IMO is more problematical to get right. That's the reason hold on wasn't done first as well plus using the x vector expicitly--when you only plot the one by itself, then you get ticks and xlimits that don't match those from bar() for the same number of bars done natively.
It's a mess...there's no really good solution given the limitations of the internals design.
Categories
Find more on Data Distribution Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!






