Multi Colors and Legend for each bar
41 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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
0 commentaires
Réponse acceptée
dpb
le 5 Août 2022
Modifié(e) : dpb
le 9 Août 2022
Slightly different, using a colorbar is nice alternative; legend is somewhat problematical owing to design of bar in that it's only a single object with one vector --
y = [467000, 150777, 20915, 229073, 95844];
x=categorical({'DG', 'PV', 'Converter', 'Battery', 'Flywheel'}); % turn x into categorical variable
figure;
hB=bar(x,y,'FaceColor','flat');
C=colororder; % retrieve default colororder vector
hB.CData=C(1:numel(y),:); % use first N
grid on
ylabel ('Net Present Cost($)','fontweight','bold','FontSize',15)
hAx=gca; % get current axes handle
hAx.YAxis.TickLabelFormat='%0.1f'; % fix up the funky numeric display
% now add a legend by faking another plot that will create the handles...
hold on
hA=area(x,nan(numel(x))); % area will be patch
hLg=legend(hA,categories(x)); % legend it...
Again, that one has to resort to workarounds to do something that should be easily done by direct action with bar continues to illustrate how poor its UI/internal design is. While such games are sometimes entertaining and intriguing to see how clever one can get, It's not productive time spent and detracts from accomplishing the real job at hand in timely manner.
The above produces(*)
(*) Sans the y axis cleanup that's not in the copy I saved/attached...
ADDENDUM:
For releases of MATLAB prior to incorporation of categorical variables on x-axis (not sure precisely when)...
figure
components={'DG', 'PV', 'Converter', 'Battery', 'Flywheel'};
y = [467000, 150777, 20915, 229073, 95844];
hB=bar(y,'FaceColor','flat');
xticklabels(components)
C=colororder; % retrieve default colororder vector
hB.CData=C(1:numel(y),:); % use first N
grid on
ylabel ('Net Present Cost($)','fontweight','bold','FontSize',15)
hAx=gca; % get current axes handle
hAx.YAxis.TickLabelFormat='%0.1f'; % fix up the funky numeric display
% now add a legend by faking another plot that will create the handles...
hold on
hA=area(nan(numel(components))); % area will be patch
set(hA,{'FaceColor'},mat2cell(hB.CData,[ones(size(y))],[3])) % set areas to match bar face colors
hLg=legend(hA,components); % legend it...
6 commentaires
Plus de réponses (1)
Adam Danz
le 5 Août 2022
Modifié(e) : Adam Danz
le 13 Nov 2022
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 commentaires
Adam Danz
le 7 Août 2022
Modifié(e) : Adam Danz
le 7 Août 2022
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])
dpb
le 7 Août 2022
Modifié(e) : dpb
le 7 Août 2022
"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.
Voir également
Catégories
En savoir plus sur Graphics Object Programming dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!