Legend is not showing all the colors - bar plot

Hi everyone!
My MATLAB code creates the bar plot you see below, however the legend outputs only two colors when in reality the bars are of 3 colors, how can I also get the legend for the blue color corresponding to 'Photos'. Thanks in advance, bye!
singleObjsPerc= rand(4,12);
TecniquesName = {'A', 'B', 'C', 'D', 'E', 'F'};
objName = {'Bottle', 'Sanitizer', 'Coffee cup', 'Notebook'};
for i = 1:4
subplot(2,2,i)
b=bar([singleObjsPerc(i,1:2); singleObjsPerc(i,3:4); singleObjsPerc(i,5:6); singleObjsPerc(i,7:8); singleObjsPerc(i,9:10); singleObjsPerc(i,11:12)],'FaceColor','flat');
aux=b(1,1);
aux.CData(1,:) = [0.9290, 0.6940, 0.1250];
title(objName{i});
set(gca,'XTickLabel',TecniquesName);
end
legend('Kinect','Photos', 'Video', 'Location', 'northwest')
Warning: Ignoring extra legend entries.

 Accepted Answer

In each subplot, you are plotting
[singleObjsPerc(i,1:2); singleObjsPerc(i,3:4); singleObjsPerc(i,5:6); singleObjsPerc(i,7:8); singleObjsPerc(i,9:10); singleObjsPerc(i,11:12)]
which is a 6x2 array. Therefore, you are plotting two sets of bars, not three.
Then, the lines
aux=b(1,1);
aux.CData(1,:) = [0.9290, 0.6940, 0.1250]
change the color of the first bar of the first group of bars (but this color change has no bearing on the fact that there are only two sets of objects).
Therefore, your legend has only two objects to assign to (which is why you get the warning about too many legend entries).
It's not clear to me what you actually intended (and also I assume this is just a toy example), so I can't really give you any more advice than that, without more detail.

4 Comments

To expand slightly:
When you legend() without passing in a list of graphic objects, then MATLAB looks for graphic objects in the current axes, and prepares one legend entry for each graphics object that it finds. It does not look inside the graphics object to see if the object has multiple colors on it and attempt to create one entry for each color grouping -- just one per object.
When you bar(), bar() creates one bar object for each column of data. 6 x 2 array, 2 bar objects created.
bar objects have their own implementation these days; historically they used to be implemented as patch() objects; they are not that different now. You would not expect legend() to create a separate legend entry for each different color in a patch() object, and you should not expect legend() to create a separate legend entry for each different color in a bar object.
If you need the first bar of the first group to be a different legend entry then the first bar of the other groups, then use multiple bar() calls -- passing in x coordinates so that they can each be positioned properly.
Thanks for the clear explanation. Now that I know how it works, it is clear to me why my code isn't working. I've tried making multiple calls to bars using x coordinates to position the bars properly, and it definitely works better; however I don't understand why I'm still getting yellow for "Photos." I think I'm missing something, but I can't understand what.
singleObjsPerc= rand(4,12);
TecniquesName = {'A', 'B', 'C', 'D', 'E', 'F'};
objName = {'Bottle', 'Sanitizer', 'Coffee cup', 'Notebook'};
for i = 1:4
subplot(2,2,i)
x = 100:100:600;
b1 = bar(100, singleObjsPerc(i,1:2), 80, 'grouped', 'FaceColor', [0.9290 0.6940 0.1250]);
hold on
b2 = bar(x(2:6), [singleObjsPerc(i,3:4); singleObjsPerc(i,5:6); singleObjsPerc(i,7:8); singleObjsPerc(i,9:10); singleObjsPerc(i,11:12)], 'grouped');
b2(1).FaceColor = [0.3010 0.7450 0.9330];
b2(2).FaceColor = [0.8500 0.3250 0.0980];
title(objName{i})
% Imposta i tick sull'asse x per ogni colonna
xticks(100:100:600)
xticklabels(TecniquesName')
% Combinazione delle legende
legend([b1 b2(1) b2(2)], {'Kinect', 'Photos', 'Video'})
end
Warning: Ignoring extra legend entries.
Warning: Ignoring extra legend entries.
Warning: Ignoring extra legend entries.
Warning: Ignoring extra legend entries.
I feel like we may be stumbling into the XY problem here. We are trying to help you fix your solution, rather than solve your fundamental problem.
It seems to me that your fundamental problem is that you are plotting two bars per group, but trying to assign three legend labels to them. Why aren't you plotting three bars, if you have three labels?
Here is a much-simplified way to plot three bars per group, with three labels correctly assigned. (Of course, I created more random data.) It seems to do everything you need. Is there anything wrong with it?
singleObjsPerc= rand(4,18);
TecniquesName = {'A', 'B', 'C', 'D', 'E', 'F'};
objName = {'Bottle', 'Sanitizer', 'Coffee cup', 'Notebook'};
for i = 1:4
subplot(2,2,i)
b2 = bar([singleObjsPerc(i,1:3); singleObjsPerc(i,4:6); singleObjsPerc(i,7:9); singleObjsPerc(i,10:12); singleObjsPerc(i,13:15); singleObjsPerc(i,16:18)], 'grouped');
title(objName{i})
xticklabels(TecniquesName')
% Combinazione delle legende
legend({'Kinect', 'Photos', 'Video'})
end
Thanks a lot for your precious help, I fixed it by doing as you said changing my singleObjsPerc matrix from 4x12 to 4x18 by putting nans where I had no data. Thanks a lot for the explanation.

Sign in to comment.

More Answers (0)

Categories

Find more on Just for fun in Help Center and File Exchange

Products

Release

R2022b

Community Treasure Hunt

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

Start Hunting!