Multi Colors and Legend for each bar

14 ビュー (過去 30 日間)
AZ Sajjad
AZ Sajjad 2022 年 8 月 5 日
編集済み: Adam Danz 2022 年 11 月 13 日 14:48
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

採用された回答

dpb
dpb 2022 年 8 月 5 日
編集済み: dpb 2022 年 8 月 9 日
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 件のコメント
dpb
dpb 2022 年 10 月 22 日
No problem, glad to help...and thank you for coming back, belatedly or not... :)

サインインしてコメントする。

その他の回答 (1 件)

Adam Danz
Adam Danz 2022 年 8 月 5 日
編集済み: Adam Danz 2022 年 11 月 13 日 14:48
Colorbar option
This is based on the solution from this thread.
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 件のコメント
dpb
dpb 2022 年 8 月 7 日
編集済み: dpb 2022 年 8 月 7 日
"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.

サインインしてコメントする。

製品


リリース

R2015a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by