Matlab: change order of entries in Figure legend

10,803

Solution 1

If your figure was generated in R2014b or newer you can utilize the undocumented 'PlotChildren' property to manipulate the order of the legend entries without requiring a new legend call.

For example:

x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;

plot(x, y1, x, y2, x, y3, x, y4);
lh = legend('y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2');

Produces:

start

Which you can then manipulate:

neworder = [3, 1, 4, 2];
lh.PlotChildren = lh.PlotChildren(neworder);

Producing:

yay

If you don't have the handle to the legend object, it is a child of the figure object containing the axes object your data is plotted on. You can find the handle to your legend object using one of the following findobj approaches:

% Handle to figure object known
lg = findobj(figureobj, 'Type', 'legend');

% Handle to figure object unknown
lh = findobj(gcf, 'Type', 'legend');

Note that gcf generally returns the handle to the last figure that the user clicked on, but this is not necessarily always the case.


Self promotion edit: This method is included in a set of legend manipulation tools maintained on GitHub by the StackOverflow MATLAB community.

Solution 2

Another alternative for those using a version of MATLAB older than R2014b is to retrieve the handles to the plot objects by specifying an output to plot. You can then re-arrange the handles in the order you want prior to passing them to legend.

x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;

hplots = plot(x, y1, x, y2, x, y3, x, y4);
labels = {'y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2'};

% Indices specifying the order in which you want the legend entries to appear
neworder = [3 1 4 2];
legend(hplots(neworder), labels(neworder));

Update

To properly handle when loading from a file, you can get all of the Children of the axes to get the plot objects and get the current legend to get the labels. You can then reorder them similar to the above approach.

load('filename.fig');

labels = get(legend(), 'String');
plots = flipud(get(gca, 'children'));

% Now re-create the legend
neworder = [3 1 4 2];
legend(plots(neworder), labels(neworder))
Share:
10,803
Patapunfate
Author by

Patapunfate

Updated on June 06, 2022

Comments

  • Patapunfate
    Patapunfate almost 2 years

    I have a Figure file where I would like to change the order of the entries (e.g., put the first entry as third one). I saved this Figure.fig long time ago so I am not sure if I can recover the original code.

    Here I show you my plot:

    My plot

    I want the legend elements to be in a decreasing order ( as in the picture) but due to a mistake my second entry is referring to the wrong plot (it says "25 years" but the plot is actually referred to the lowest trend, corresponding to the "9 years" trend).

    Can I switch the order of the entries in the Legend directly from the Properties Editor of the Figure in Matlab? If yes, how (I did not see any "Order" property or similar)? Otherwise is there any other simple approach to switch the order of the entries in the Legend?

  • Sembei Norimaki
    Sembei Norimaki almost 8 years
    Is there a particular reason to avoid calling legend again and instead using an undocumented function?
  • sco1
    sco1 almost 8 years
    @SembeiNorimaki because it maintains the link between the lineseries and the legend entry.
  • Emil
    Emil almost 7 years
    This is great! However I'm having trouble getting this to work in R2017a or b. Assigning the children in the new order just doesn't do anything (also when using the 'set' method). It still works fine in R2016b. Any ideas?
  • sco1
    sco1 almost 7 years
    Hi @Emil, unfortunately the improvements to the graphics engine introduced in R2017a broke most of this functionality. One of the hazards of working with undocumented functionality; unfortunately I have not yet had time to investigate alternative methods.
  • z8080
    z8080 about 2 years
    Thanks so much for providing this one piece of information that makes this trick work. Good to see a small part of SO is still interested in Matlab :)