Sort producing inconsistent results when re-ordering legend

5 ビュー (過去 30 日間)
Ben
Ben 2023 年 2 月 15 日
コメント済み: Ben 2023 年 2 月 15 日
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.

採用された回答

Voss
Voss 2023 年 2 月 15 日
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 件のコメント
Ben
Ben 2023 年 2 月 15 日
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.

サインインしてコメントする。

その他の回答 (1 件)

Jan
Jan 2023 年 2 月 15 日
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 件のコメント
Ben
Ben 2023 年 2 月 15 日
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

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLegend についてさらに検索

製品


リリース

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by