Clear Filters
Clear Filters

Sort producing inconsistent results when re-ordering legend

5 views (last 30 days)
Hi everyone,
I have a plot which I am attempting to reorder the legend of (ideally without having to do so manually). I was attemping to do this by reordering/sorting the line object.
However, every time I run the script, despite the sorting being specified, the order of the legend changes randomly each run (the order of 500, 200 and 1500 in the exmaple below). I've tried pre-defining sorting indexes which I can verify stay consistent between runs but I still get this same issue. I do not know if this is a bug or (more probably) a misunderstanding on my part.
If you can help me out with this and provide some solutions/alternative methods, please let me know as it would be much appreciated!
I've got an except of code below which replicates this odd behaviour. Thanks!
clear all
close all
y = rand(100,3);
x = 1:100;
a = 3;
b = 0;
Names = {'500' '200' '1500'};
for n=1:3
plot(x,y(:,n),'DisplayName',Names{n})
b = b+1;
hold on
if a==b
lines = sort(findobj(gca,'type','Line'))
legend(lines)
title(legend,'Names')
end
end
lines =
3×1 Line array: Line (500) Line (200) Line (1500)
PS. for anyone wondering why I'm using DisplayName instead of defining the legend afterwards, I was having further issues trying to generate the legends in this way, although again any tips would be helpful!
Edit: I've tested it further by moving the sort function onto the line below but the problem persists so I believe the issue is somewhere in the sort function.

Accepted Answer

Voss
Voss on 15 Feb 2023
Rather than relying on findobj, capture the output from plot, which is the line handle(s), and use those in legend.
clear all
close all
y = rand(100,3);
x = 1:100;
Names = {'500' '200' '1500'};
num_lines = size(y,2);
lines = zeros(num_lines,1);
for n = 1:num_lines
lines(n) = plot(x,y(:,n),'DisplayName',Names{n});
hold on
end
% reorder lines here if needed, e.g.:
[~,idx] = sort(str2double(Names));
lines = lines(idx);
leg = legend(lines);
title(leg,'Names')
PS. I think using DisplayName is a good idea.
  1 Comment
Ben
Ben on 15 Feb 2023
Thanks - this works just as I needed! In my example I've pre-sorted the categories and kept in the if loop from my example (personal preference), but the syntax is still the same.

Sign in to comment.

More Answers (1)

Jan
Jan on 15 Feb 2023
lines = sort(findobj(gca,'type','Line'))
This is a bad idea. findobj replies the handles to the line objects. To feed sort with useful inputs, they are converted to the old double values, which have been used as handles in old Matlab versions until 2014.
I do not understand, what the wanted sorting order is. Maybe the alphabetical order of the names?
  1 Comment
Ben
Ben on 15 Feb 2023
Yes, alphabetical sorting ideally, although in my actual dataset my legend entries are numeric, so I'm also looking for a workaround to get them in numerical order e.g. '200 500 1500' instead of the alphabetically ordered '1500 200 500'. Thanks

Sign in to comment.

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!