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

6 Ansichten (letzte 30 Tage)
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 Kommentare
Lorenzo Chiaverini
Lorenzo Chiaverini am 31 Mär. 2021
Bearbeitet: Lorenzo Chiaverini am 31 Mär. 2021
yes, (it is already pretty slow and i was trying to optimise it)
Jan de Jong
Jan de Jong am 31 Mär. 2021
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.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Steven Lord
Steven Lord am 31 Mär. 2021
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 Kommentare
Lorenzo Chiaverini
Lorenzo Chiaverini am 1 Apr. 2021
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 am 10 Apr. 2021
Just to let everybody interested know, now the plotting time is a way faster, from 200s to about 10. Thank you again.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Creating, Deleting, and Querying Graphics Objects finden Sie in Help Center und File Exchange

Produkte


Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by