Multi Colors and Legend for each bar
41 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
AZ Sajjad
el 5 de Ag. de 2022
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 comentarios
Respuesta aceptada
dpb
el 5 de Ag. de 2022
Editada: dpb
el 9 de Ag. de 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 comentarios
dpb
el 22 de Oct. de 2022
No problem, glad to help...and thank you for coming back, belatedly or not... :)
Más respuestas (1)
Adam Danz
el 5 de Ag. de 2022
Editada: Adam Danz
el 13 de Nov. de 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 comentarios
Adam Danz
el 7 de Ag. de 2022
Editada: Adam Danz
el 7 de Ag. de 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
el 7 de Ag. de 2022
Editada: dpb
el 7 de Ag. de 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.
Ver también
Categorías
Más información sobre Graphics Object Programming en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!