How do I make a legend for data organized into colours in a bar plot?
Show older comments
Hello, I have data (see attached figure) which is grouped together by colour. I would like to have a legend that which explains what each colour grouping is defined by. I can only find legend creation questions about creating legends on the actual x-axis data, instead of the colour by which I organized it.
Is there a way to do this? I organized my data by colour as follows:
for i = 1:length(Names)
switch Names(i)
case{'Pu','Am','Np','Cm'}
Yield.CData(i,:) = [255 0 0];
case{'Mo','Ru','Tc','Rh','Zn','Ga'}
Yield.CData(i,:) = [0 255 0];
case{'Ce','Nd','Eu','Sm','Sc','Y','La'}
Yield.CData(i,:) = [255 255 0];
case{'Li','Na','K','Rb','Cs','Fr'}
Yield.CData(i,:) = [0 0 0];
case{'O','Xe','Te'}
Yield.CData(i,:) = [255 255 255];
end
end

If someone could provide an answer or some insight I would greatly appreicate it.
~ Dan
1 Comment
dpb
on 8 Mar 2019
So, what do you want legend to be?
Accepted Answer
More Answers (1)
The bar plot/object in Matlab is a really, Really, REALLY difficult thing to work.with, unfortunately.
A single bar plot has only one bar object as you've drawn it above and, therefore, you can only assign one legend string because there is only a single graphic object on the plot to assign the legend to.
You can "fake" it by creating a hidden grouped bar with two rows by the number of columns that you have colors, in this case five (5) and then assigning those bar objects the desired colors and use legend() on them.
A dummy example with the "real" data being five bars and four dummy colors
hB=bar(abs(randn(1,5))); % generates one bar handle with five bars
hB.FaceColor='flat'; % ready to set color by bar w/ CData
hB.CData(1,:)=[255 0 0]; % first and
hB.CData(3,:)=[255 0 0]; % third red
hB.CData(2,:)=[0 255 0]; % second green
hB.CData(5,:)=[255 255 255]; % fifth white, leaves fourth default
hold on % set hold state to add onto plot
hBB=bar(nan(2,4)); % now create the dummy four bar handles
hBB(1).FaceColor=[1 0 0]; % FaceColor is normalized 0, 1 instead of rgb -- red
hBB(2).FaceColor=[0 1 0]; % green
hBB(3).FaceColor=[0 0 1]; % blue
hBB(4).FaceColor=[1 1 1]; % white
hLG=legend(hBB,'A','B','C','D','location','northwest'); % write legend for the colored bars
The above creates the following figure--

I've railed for years about bar; TMW really should totally redesign a new replacement that isn't so difficult to use for obvious needs.
6 Comments
Dan Hallatt
on 9 Mar 2019
Edited: dpb
on 9 Mar 2019
dpb
on 9 Mar 2019
It's really not the legend() part that's hard; it's the way they designed bar() such that a single column or row generates only one graphic object.
It's the kludge to create the number of bar() object handles that you need to match the number of legends you want to write that's the pain.
It's possible you might be able to recast your data into a grouped format to generate the number of handles needed directly but I just approached to add the legend to the existing plot.
If you'd attach a sample dataset, if had time I might try to see if can go at it in a slightly more direct manner.
Dan Hallatt
on 9 Mar 2019
dpb
on 9 Mar 2019
"... it doesn't overlay the legend onto the same plot, but instead makes its own figure window and shows the legend there with the dummy/fake bar graph."
No. Altho I see I did omit the key line hold on before creating the dummy bar plot objects to overlay the existing "real" bar plot that is the desired data.
I fixed that oversight in the answer; insert the same in your code before the dummybar= line
Dan Hallatt
on 9 Mar 2019
I tried to recast the problem to use a 2D array to generate an array of bar handles to color but BAR() is just too inflexible--when you create a grouped bar, then it forces the center of each group to the location of the row index in the input array and won't let you locate individual bars.
The only alternative to the above "trick" I see is to create N bar plots, each of which then contains only the desired elements for the given set, but has NaN for all the other elements. Building those arrays is also a convoluted mess of coding.
All in all, my previous remarks still hold--TMW needs to introduce a whole new barplot routine that one could do something with.
I did rewrite your code a little and posted a second answer...but yours will work with just the addition of the hold on line I didn't get pasted in the example and fixing up some of the labels and so on. I'm not sure what your intent was there...
Categories
Find more on Annotations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!