How to Create a Static Legend for a Dynamic Axes

조회 수: 7 (최근 30일)
Caleb Thomas
Caleb Thomas 2017년 7월 17일
답변: Breno Vincenzo de Almeida 2020년 10월 6일
I have written a GUI for interaction with and tracking of the Lorenz Attractor. The 3D plot is in the main figure, but the user can open a separate figure that displays the position-time graph for each coordinate direction. This component plot deletes the data from the graph handle as soon as it leaves the lower axis range to avoid consuming my memory (the data essentially scrolls across the axes). It currently has a very good running speed, but I cannot figure out how to add a legend to the component plot without slowing down performance. Even if I turn auto-update off and only create the legend for the first set of points plotted, it somehow still finds a way to slow down my program significantly as it continues to run. Is there a way to assign the legend initially and then make it entirely static, so it is essentially just an image overlaid on the axis?
Here is my code for the plotting loop that currently has the legend statement commented out
if true
%animation plotting loop
ch = 0;
ck = 0;
for i = 2:length(t)
if ~triggers.stop
triggers.i = i;
triggers.startPos.Update = [a(i, 1), a(i, 2), a(i, 3)];
h(i-ch) = plot3(ax1, a(i-1:i,1),a(i-1:i,2),a(i-1:i,3), linestyle, 'color', color);
if i > nTrim && nTrim ~= 0
delete(h(2))
h(2) = [];
ch = ch+1;
end
if triggers.comp && mod(i, 2) == 0 && i > kBuffer
xlim(ax3, [t(i)-tGRange, t(i)]);
ylim(ax3, [min(min(a)), max(max(a))]);
k(:, triggers.kk-ck) = plot(ax3, t(i-kBuffer:i), a(i-kBuffer:i, 1), '-k', t(i-kBuffer:i), a(i-kBuffer:i, 2), '-r', t(i-kBuffer:i), a(i-kBuffer:i, 3), '-c');
% if triggers.kk == 2
% legend(ax3, k(:,2), {'X Position', 'Y Position', 'Z Position'}, 'AutoUpdate','off')
% end
if k(1, 1).XData < t(i)-tGRange
delete(k(:, 1))
k(:, 1) = [];
ck = ck+1;
end
triggers.kk = triggers.kk + 1;
end
pause(pauseTime)
else %break statement for terminating program
break
end
end
triggers.stop = false;
end
end

채택된 답변

Don Zheng
Don Zheng 2017년 7월 20일
Try setting the XData/YData/ZData properties of the plots rather than calling 'plot'/'plot3' each time in the loop. For example:
close all;
figure;
ax = axes;
px = plot(ax, 0, 0, 'x'); hold on;
py = plot(ax, 0, 0, 'o');
legend(ax, {'x dir', 'y dir'});
deg = 0:720;
xv = sind(deg);
yv = cosd(deg);
scope_width = 50;
for i = deg+1
range = i:min(numel(deg),i+50);
px.XData = deg(range);
px.YData = xv(range);
py.XData = deg(range);
py.YData = yv(range);
xlim([px.XData(1), px.XData(1)+scope_width]);
ylim([-1, 1]);
pause(0.01);
end
  댓글 수: 1
Caleb Thomas
Caleb Thomas 2017년 7월 21일
Thank you! That is much better than the method I had been using, especially when it came to trimming the data. I had not considered simply augmenting the handles data matricies themselves, that is quite crafty. The performance still takes a bit of a hit when the components are opened, naturally, but the effect does not compound over time and overall it still runs at a reasonable speed, but still not at the same speed as no legend at all. I'm afraid it may just be the extra graphics and handle putitng a strain on my system (even though they should be very lightweight?)
Thank you again for your help!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Breno Vincenzo de Almeida
Breno Vincenzo de Almeida 2020년 10월 6일
In addition to Don Zheng's answer, you can set the legend to auto update off.
Using his example as reference, just do:
lgd = legend(ax, {'x dir', 'y dir'});
lgd.AutoUpdate = 'off';

카테고리

Help CenterFile Exchange에서 Legend에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by