manipulating plot legend, assigning colours

Hello,
I have complex data which I want to plot. My code is:
if true
% code
end
for bb = 1:size(Data.Measured,2)
%calculating how many measurements we have for right and left ear
idx1 = strfind(Data.Side, 'Right');
idx1 = find(not(cellfun('isempty',idx1)));
N (bb) = length(idx1);
idx2 = strfind(Data.Side, 'Left');
idx2 = find(not(cellfun('isempty',idx2))) ;
M (bb) = length(idx2) ;
for kk = 1:size(Data.Name,2)
if strcmpi(Data.Side{kk}, 'Right')
subplot(2,1,1)
Data.legend.sub1{c1} = regexprep(Data.Name{kk},'_',' ');
c1 = c1+1;
legend(Data.legend.sub1(1:N))
title([name(bb),' Right'])
else
subplot(2,1,2)
title([name(bb),' Left'])
Data.legend.sub2{c2} = regexprep(Data.Name{kk},'_',' ');
c2 = c2+1;
legend(Data.legend.sub2(N+1:N+M))
end
end
the problem I have here is that my Data.legend.sub1 and Data.legend.sub2 give me all measurements done for all subjects but in reverse order:
Data.legend.sub1
Data.legend.sub2
Thus, my legend is using different colours for different measurements. First, I want to make sure that I am only plotting measurements for right side (is it already ensured by line :if strcmpi(Data.Side{kk}, 'Right')?). second I want to use the same colours for the same measurement for both sides. third, I am not sure why I am getting warning 'Ignoring extra legend entries.' and then one measurement is always omitted in the legend and specified just as 'data 1'...
I hope my explanation is clear.

8 Comments

Try to put those legend outside the for loop
for kk = 1:size(Data.Name,2)
if strcmpi(Data.Side{kk}, 'Right')
a=subplot(2,1,1)
Data.legend.sub1{c1} = regexprep(Data.Name{kk},'_',' ');
c1 = c1+1;
title([name(bb),' Right'])
else
b=subplot(2,1,2)
title([name(bb),' Left'])
Data.legend.sub2{c2} = regexprep(Data.Name{kk},'_',' ');
c2 = c2+1;
end
end
legend(a,Data.legend.sub1(1:N))
legend(b,Data.legend.sub2(N+1:N+M))
'Ignoring extra legend entries.' means your legend labelling more than the lines.
In the same time, i suspect there is empty cell in Data.legend.sub1 and Data.legend.sub2.
Do you mind to display those variables?
display(a,Data.legend.sub1)
display(b,Data.legend.sub2)
and post the display result here.
if true
% code
end
if strcmpi(Data.Side{kk}, 'Right')
a(kk) = subplot(2,1,1)
Data.legend.sub1{c1} = regexprep(Data.Name{kk},'_',' ');
c1 = c1+1;
title([name(bb),' Right'])
else
b(kk)=subplot(2,1,2)
title([name(bb),' Left'])
Data.legend.sub2{c2} = regexprep(Data.Name{kk},'_',' ');
c2 = c2+1;
end
legend(a,Data.legend.sub1)
legend(b,Data.legend.sub2)
this gives me an error that b doesn't exist. I think it is only because b subplot is only created when the a subplot is done so it can't really be outside the loop...
Do you mind to display those variables?
display(a,Data.legend.sub1)
display(b,Data.legend.sub2)
and post the display result here. I want to see why there is data1.
>> display(b,Data.legend.sub2)
Error using matlab.graphics.Graphics/display Invalid input for argument 2 (rhs2): Value must be a character vector or string scalar.
>> display(a,Data.legend.sub1)
Error using matlab.graphics.axis.Axes/display Invalid input for argument 2 (rhs2): Value must be a character vector or string scalar.||
jonas
jonas on 16 Oct 2018
Edited: jonas on 16 Oct 2018
@KDRA,
Did you even try any of the methods given in my answer? It's really simple, the plot in itself is not complex at all.
Make it simple for people to help you. You have posted only parts of the code (there is no plot call?)... and obviously key information is missing.
With regard to the part of the question in the title (which appears to be only a small part!) you shouldn't be attempting to manipulate colours in a legend. The legend takes the colours from the plots it is referring to. Change the plot colours if they are not as you wish, and the legend will reflect this, but you shouldn't be independently trying to change colours in the legend itself.
Hi Adam, good point. What I meant is not overwriting the colours but assigning for example R0 measutement to blue colour, R7 to red, etc. This may be challenging though because my legend labels and measurement results are in different layers of the cell array. I am not too sure how I would do it...
The colours in the legend should still reflect the colours of the lines though otherwise what is the point of the legend?

Sign in to comment.

 Accepted Answer

jonas
jonas on 16 Oct 2018
Edited: jonas on 16 Oct 2018
Always output the plot handle.
h = plot(...)
If you are plotting in a loop, then save all handles.
h(i) = plot(...)
You can add the legend outside of your loop, by passing all the handles (in the desired order) and a cell array of legend entries.
legend(h,{leg1,leg2,leg3})
or perhaps you want them in reversed order
legend(flipud(h),{leg1,leg2,leg3})
Another alternative would be to pass the legend entry directly to your plot.
plot(...,'displayname',legn)
and then simply pass the handles to the legend
legend(h)
If you use any of the above methods, you should never again run into the warning 'ignoring extra legend entries'. Just make sure that the size of your cell array with legend entries matches the size of the array with handles.

5 Comments

Hi Jens,
I did try your solution as well but it also did not work. The code is really long so I didn't want to spam but the plot call is at the very beginning. Whn I try your method:
if true
% code
end
if strcmpi(Data.Side{kk}, 'Right')
a(kk) = subplot(2,1,1)
Data.legend.sub1{c1} = regexprep(Data.Name{kk},'_',' ');
c1 = c1+1;
title([name(bb),' Right'])
else
b(kk)=subplot(2,1,2)
title([name(bb),' Left'])
Data.legend.sub2{c2} = regexprep(Data.Name{kk},'_',' ');
c2 = c2+1;
end
legend(flipud(a),Data.legend.sub1)
legend(flipud(b),Data.legend.sub2)
I am getting error message that b is undefined. It is because of the same reason as in Kevin's solution - because in the loop it only plots a subplots first (right side) and only when it's done it plots the left side (b). I tried placing legend command completely outside the loop but it gives me another error.
Also I don't fully understand the last two lines of your suggested solution (the alternative solution) so I only tried the first part.
You can always upload the .m-file if the code is long. It is quite surprising that the b is unassigned. Is it perhaps assigned within a function call or cleared at some point?
Although I always suggest to organize your handles, the second method I proposed is quite convenient. Basically, you assign displaynames to the line objects, that are embedded and easily transferred to the legend function. Try this for example:
plot(rand(10,1),'displayname','legend1')
legend
I'd be happy to take a look at your .m-file, if you'd be willing to upload. I suspect that there is room for improvement ;)
Hi Jonas, I changed the approach for my code a little bit (basically the format of my variables) but I used your advices for plotting and it worked perfectly. Thanks a lot!
Always happy to help! Cheers!

Sign in to comment.

More Answers (0)

Asked:

on 16 Oct 2018

Commented:

on 24 Oct 2018

Community Treasure Hunt

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

Start Hunting!