An Efficient way of generating a legend for 'for loops plots'

6 ビュー (過去 30 日間)
Lorenzo Chiaverini
Lorenzo Chiaverini 2021 年 3 月 31 日
コメント済み: Lorenzo Chiaverini 2021 年 4 月 10 日
Dear all,
I wrote a matlab code to plot various data from a FEM analysis. My problem is creating a legend efficiently. The code uses for loops to plot an different objects multiple times. If i do not specify the objects clearly, the legend function will see thousands of different graphic objects. For this reason my code does something similar to this:
for i = 1 : n
h = plot3(variable(i, 1), variable(i, 2), variable(i, 3));
end
legend(h, 'myvariable')
(the only difference is that h actually stores the information from different lines/data, it is a vector of handles).
The thing i do not like is that i am saving the information about my graphic object multiple time. I have not tested this but i think is clear it will increase the overall plotting time (the amount of data i am plotting can be really large). My solution to this was the following:
h = 0;
for i = 1 : n
if h == 0
h = plot3(variable(i, 1), variable(i, 2), variable(i, 3));
else
plot3(variable(i, 1), variable(i, 2), variable(i, 3));
end
end
legend(h, 'myvariable')
This is likely to work but it will double the length of my code that right now is already 540 lines. Honestly i prefer a compact code, hence my questions: is there any other solution apart from the one I proposed? does anybody have any idea on how i can solve this problem? Am i doing it right?
Thank you!
(PS note: the for loops are necessary, i need to plot line segments which are not connected to each other)
  5 件のコメント
Lorenzo Chiaverini
Lorenzo Chiaverini 2021 年 3 月 31 日
編集済み: Lorenzo Chiaverini 2021 年 3 月 31 日
yes, (it is already pretty slow and i was trying to optimise it)
Jan de Jong
Jan de Jong 2021 年 3 月 31 日
One way of avoiding a multitude of line segments you could store the variables into a single vector interleaved with nans.
var1 = randn(6,3);var2 = randn(6,3);
mastervar = [var1;nan(1,3);var2];
plot3(mastervar(:,1),mastervar(:,2),mastervar(:,3))
I do not think storing handle h to your plot will increase the computational burden. It is just a link.

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

採用された回答

Steven Lord
Steven Lord 2021 年 3 月 31 日
Two suggestions:
1) When you create the graphics object, set its DisplayName property. Then when you want to show the legend, you won't have to specify the names.
x = 0:360;
axis([0 360 -1 1])
hold on
h = gobjects(1, 2);
h(1) = plot(x, sind(x), 'DisplayName', 'sine');
h(2) = plot(x, cosd(x), 'DisplayName', 'cosine');
legend
% or to show just one
legend(h(2))
2) If the lines that you're drawing are all part of the same "thing", rather than creating a lot of small (2 point) line objects you can include NaN values in your data to be plotted to break the line at that point.
figure
x = 1:15;
x(mod(x, 3) == 0) = NaN;
h = plot(x, x)
h =
Line with properties: Color: [0 0.4470 0.7410] LineStyle: '-' LineWidth: 0.5000 Marker: 'none' MarkerSize: 6 MarkerFaceColor: 'none' XData: [1 2 NaN 4 5 NaN 7 8 NaN 10 11 NaN 13 14 NaN] YData: [1 2 NaN 4 5 NaN 7 8 NaN 10 11 NaN 13 14 NaN] ZData: [1×0 double] Show all properties
5 line segments visually, but just one graphics object in memory.
  4 件のコメント
Lorenzo Chiaverini
Lorenzo Chiaverini 2021 年 4 月 1 日
I see, that is great. Yes i am adding arrows in a loop, i will try to preallocate the object as you said and see what happens. Thank you!
Lorenzo Chiaverini
Lorenzo Chiaverini 2021 年 4 月 10 日
Just to let everybody interested know, now the plotting time is a way faster, from 200s to about 10. Thank you again.

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

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeCreating, Deleting, and Querying Graphics Objects についてさらに検索

製品


リリース

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by