Clear Filters
Clear Filters

Create aditional legend on bar chart

1 view (last 30 days)
Tiago Dias
Tiago Dias on 4 Jun 2019
Edited: dpb on 4 Jun 2019
Hello,
I got a bar chart, and i want to have the bars with different colors. I would like to know if it possible to show sometype of legend in funciton of colors.
I would like to show up, red saying Reaction, green for pressure and etc.
This way i can only show the first one and not able to show the rest.
X = [10 17 3 25 31 20 11 13 14];
myC = [1 0 0; 0 1 0; 1 0 1; 0 0 1; 0.5 0 0.5; 1 0.5 1; 0.5 0 0; 0 0.5 0; 1 0 0.5];
figure();
fig = bar(X);
fig.FaceColor = 'flat';
% hold on
fig.CData(1,:) = [1 0 0];
fig.CData(2,:) = [0 1 0];
fig.CData(3,:) = [1 0 1];
fig.CData(4,:) = [0 0 1];
fig.CData(5,:) = [0.5 0 0.5];
fig.CData(6,:) = [1 0.5 1];
fig.CData(7,:) = [0.5 0 0];
fig.CData(8,:) = [0 0.5 0];
fig.CData(9,:) = [1 0 0.5];
lgd = legend(fig,{'Reaction';'Pressure';'Load';'Separation';'Tanks';'valves';'XV';'TIC';'Hydrogen'},'location','best');
If not possible, other suggestion is welcome!
Thanks for your time,
Tiago

Accepted Answer

dpb
dpb on 4 Jun 2019
Edited: dpb on 4 Jun 2019
Oh, the infamous bar again! What a difficult implemtation it is to do anything with... :(
Believe it or not, you must do something like the following--
M=diag(X);
figure
hB=bar(M,'stacked');
arrayfun(@(i) set(hB(i),'FaceColor',myC(i,:)),1:numel(hB))
hLg=legend({'Reaction';'Pressure';'Load';'Separation';'Tanks';'valves';'XV';'TIC';'Hydrogen'},'location','best');
to convince bar to put multiple bar objects on a figure without grouping them. This is necessary because while you can set an individual color by bar on a single object, legend can only label one per handle graphics object and all the bars drawn are one object when using a vector; there's no option otherwise.
I always suggest to add your voice to the copious complaints/suggestions I've made in the past and submit enhancement requests/quality of implementation/documentation on the bar function. It's incredibly difficult to work with as is and needs all kinds of these bizarre workarounds to do the most obvious of things...try to put a label on each bar and see how much fun that turns into, too...
ADDENDUM
BTW, you can shorten the arrayfun() option to set multiple properties with a single call to set if you turn the colors array into cell array--
myC=cell2mat(myC,ones(1,size(myC,1)));
set(hB,{'FaceColor'},myC)
  2 Comments
Tiago Dias
Tiago Dias on 4 Jun 2019
Edited: dpb on 4 Jun 2019
Thanks for your input on the subject.
After a long search on the problem I found this code, for future help to someone
The goal here is to place the bar at position 1 2 3and 5 in blue, and the others in red with 2 strings of legend. I manage to do that this way:
X = [10 17 3 25 31 20 11 13 14];
Pressure = [1 2 3 5];
Reaction = [4 6 7 8 9];
figure();
h_bar1 = bar(Pressure,X(Pressure)','b');
hold on
h_bar2 = bar(Reaction,X(Reaction)','r');
hold off
set(gca,'XTick',[1:9]);
legend('Pressure','Reaction')
dpb
dpb on 4 Jun 2019
Edited: dpb on 4 Jun 2019
That's essentially same solution by another route to create multiple bar handles on same axes. But, a somewhat different problem than the Question! :)
hBar=bar(M,'stacked');
set(hBar(Pressure),'FaceColor','r')
set(hBar(Reaction),'FaceColor','b')
legend(hBar([Pressure(1) Reaction(1)]),'Pressure','Reaction')

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!