matlab

# Matlab: flip legend order and legend overlapping plots after saving

I'm trying to reverse my legend entries order based on reverse ordering of legend colors in matlab bar plot, but it doesn't seem to work in my case.

Basicaly what I have is a GUIDE figure, that draws a lot of plots and is able to save them to a .png file. The effect looks like this:

I've managed to change the text order by flipping legend upside-down, but I can't change legend colors order. Here's what I've got:

``````[a b] = legend(legenda);

map = colormap; % current colormap

n = size(b,1);

z = linspace(size(map,1),1,n/3); % there is 1 text and 2 line elements for every data series, so I divide by 3

z = round(z); %otherwise matlab gets angry that indices must be real integers or logicals

MAP = map(z(:),:); % gets elements specified by linspace from colormap
``````

So far everything works ok.

The b vector for two series looks like this (starts with 2.0, because it's reversed):

``````Text    (P+C 200 2.0.dpt)
Text    (P+C 200 1.0.dpt)
Line    (P+C 200 2.0.dpt)
Line    (P+C 200 2.0.dpt)
Line    (P+C 200 1.0.dpt)
Line    (P+C 200 1.0.dpt)
``````

So I figured out (based on the linked code), I have to change the color variable for every line entry.

``````for k = (n/3 + 1):n
a1 = get(b(k),'Children');
set(a1,'FaceColor',MAP(ceil((k - n/3)/2), :));
end
``````

Ceil and dividing by 2 gives the same index twice.

This code, however, does nothing.

I've checked whether flipping the legend vector may be the source of my problems, but the color order stays the same. I've tried with MAP vector too - no luck.

When I remove the semicolon after the a1 = ... line in the for loop, I get:

``````a1 =

0x0 empty GraphicsPlaceholder array.
``````

How can I get this to work?

Also, is there any good way to make the legend not cover the plots after it's saved (see picture linked above)?

The way I save it is by creating a temporary figure with 'visible' 'off' and doing a copyobj of axes and legend, then saving. Otherwise it saves the whole figure.

Solution

• The reason for which the code provided in the answer to reverse ordering of legend colors in matlab bar plot does not work in your case is because in that case (plot of a `bar` chart) the object in the legend are `patches` while in your plot they are `lines`.

The `FaceColor` only applies to patches and not to `lines`.

The easiest way to solve you probles should be to reverse the order in which you plot the lines "since the beginning" and, doing that, directly using the set of colors you extract from the `colormap`.

Nevertheless, if you wnat to work with the `legend` after having plotted the graph, beside revrsing the items in the `legend` you have also to change the color of the lines in the plot, if you want to use the set of color extracted from the `colormap` (at present in your picture, some lines share the same color).

To can solve the problem in two steps:

• revert the string in the legend and change the colors of the line sin the plot
• update the color of the lines in the legend accordingly

The two steps are required since, when you change the color of the lines in the plot, the items in the legend are updated automatically.

With reference to the code youy've posted: you can access to the legend's string and line's color through the array `b`.

You can access to the handles of the lines plotted as follows:

``````p_h=get(gca,'children')
``````

Since you have plotted 10 lines, the array `b` is build as follows:

• b(1:10) contains the handles to the `string`
• b(11:2:30) contains the handles to the `lines`
• b(12:2:30) contains the handles to the `markers`

To chenge the positin of the legend you can set its `location` property: to put it outside the `axes` you can set it either to:

``````    'NorthOutside'       outside plot box near top
'SouthOutside'       outside bottom
'EastOutside'        outside right
'WestOutside'        outside left
'NorthEastOutside'   outside top right (default for 3-D plots)
'NorthWestOutside'   outside top left
'SouthEastOutside'   outside bottom right
'SouthWestOutside'   outside bottom left
``````

In the following you can find the code in which the above suggestions have been implemented.

``````figure
% Initial plot
h_p=plot(0:.1:2*pi,bsxfun(@plus,sin([0:.1:2*pi]),[3:3:30]'),'linewidth',3)
% Initial legend
[h_leg,b]=legend(cellstr(strcat(repmat('sin(x)+',10,1),num2str([3:3:30]'))))
%
% YOUR CODE TO GENERATE NTHE NEW COLORS
%
map = colormap; % current colormap
n = size(b,1);
z = linspace(size(map,1),1,n/3); % there is 1 text and 2 line elements for every data series, so I divide by 3
z = round(z); %otherwise matlab gets angry that indices must be real integers or logicals
MAP = map(z(:),:); % gets elements specified by linspace from colormap
%
% Reverse the legend strings
%
rev_str=flipud(get(b(1:10),'string'))
%
% Get the handles of the lines in the legend
%
b1=b(11:2:30)
%
% Revere the string in the legend
% and update the color of the lne in the plot using the colors defined in
% MAP
%
p_h=get(gca,'children')
for i=1:10
set(b(i),'string',rev_str{i})
set(p_h(i),'color',MAP(i,:),'linewidth',3)
end
%
% Reverse the color of the lines in the legend
for i=1:10
set(b1(i),'color',MAP(i,:),'linewidth',3)
end
%
% Move the legend outside the axes
%
set(h_leg,'location','NorthEastOutside')
``````

Original Plot

Updated plot

Hope this helps.