Smoothly interact (pan, rotate, zoom) with an updating figure (animation).

22 views (last 30 days)
Hello all,
I am attempting to allow user interactions such as pan and rotate with a figure, where the contents of the figure are rapidly updating. This is a question of whether the below method is, in fact, the best way of doing this. I find that this method leaves the resulting animation a little choppy, and the interactions sometimes don't work; the rotate tool, for example, takes multiple clicks to "connect". I think this is due to the click occuring in the wrong part of the loop.
I will use an updating, Brownian motion demo just as a test. It parallels other codes where I am using hold to plot several layers of data.
% Set up our figure, and starting view and limits
figure;
targAxes = gca;
view(targAxes,[103, 8]);
axis([-15 15 -15 15 -15 15]);
% Define a function for rand that is on [-1 1]
randz = @(sz1,sz2) 2*(rand(sz1,sz2) - .5);
% Initialize 3 different sets of points
pos1 = randz(1000,3);
pos2 = 2*randz(1000,3);
pos3 = 10*randz(1000,3);
% Run a loop for a while
for ii = 1:600
% Get current view and axes
cv = targAxes.View;
ca = [targAxes.XLim, targAxes.YLim,targAxes.ZLim];
% Clear the figure, and plot our 3 sets of points
hold(targAxes,'off');
plot3(pos1(:,1),pos1(:,2),pos1(:,3),'b.','Parent',targAxes);
hold(targAxes,'on');
plot3(pos1(:,1),pos2(:,2),pos2(:,3),'g.','Parent',targAxes);
plot3(pos3(:,1),pos3(:,2),pos3(:,3),'r.','Parent',targAxes);
% Set the view to the "current view": I HAVE to do this, or the first
% call to plot3 resets the view.
view(targAxes,cv);
axis(targAxes,ca);
% Draw our plots
drawnow;
% Add some random motion to keep things interesting
mv1 = randz(1000,3)/100;
mv2 = randz(1000,3)/50;
mv3 = randz(1000,3)/10;
pos1 = pos1 + mv1;
pos2 = pos2 + mv2;
pos3 = pos3 + mv3;
end
Nominally, I would want to set the current view during the plot3 command: I think the issues are that
  • There is some latency for each of the plot3 commands (not just drawnow), and so there is a dead period where changes in the view/pan will not be recorded
  • If a mouse click occurs during this dead period, it doesn't seem to always connect.
  • The dead period also leads to some appearance of jitter, where the view resets slightly at the end of the dead period. This will get worse the longer the dead period is.
  • Rapid pans and rotates get reset due to this dead period.
Since each plot3 command resets the view to [1 1 1] (or something like that) I cannot recapture the view after each plotting command.
So, is there a better way of doing this to improve smoothness/interactability?
Cheers,
-DP

Answers (1)

Luc
Luc on 8 Feb 2021
Hello,
You could try updating the plot data instead of reploting it.
It avoids resetting the view, and gains some time other recalling plot3.
The result seems more fluid.
Regards,
LK
% Set up our figure, and starting view and limits
figure;
targAxes = gca;
view(targAxes,[103, 8]);
axis([-15 15 -15 15 -15 15]);
% Define a function for rand that is on [-1 1]
randz = @(sz1,sz2) 2*(rand(sz1,sz2) - .5);
% Initialize 3 different sets of points
pos1 = randz(1000,3);
pos2 = 2*randz(1000,3);
pos3 = 10*randz(1000,3);
% Plot our 3 sets of points for once
hold(targAxes,'on');
hdp1=plot3(pos1(:,1),pos1(:,2),pos1(:,3),'b.','Parent',targAxes);
hdp2=plot3(pos2(:,1),pos2(:,2),pos2(:,3),'g.','Parent',targAxes);
hdp3=plot3(pos3(:,1),pos3(:,2),pos3(:,3),'r.','Parent',targAxes);
% Run a loop for a while
for ii = 1:600
% Add some random motion to keep things interesting
mv1 = randz(1000,3)/100;
mv2 = randz(1000,3)/50;
mv3 = randz(1000,3)/10;
pos1 = pos1 + mv1;
pos2 = pos2 + mv2;
pos3 = pos3 + mv3;
% Update the plot data
hdp1.XData = pos1(:,1);
hdp1.YData = pos1(:,2);
hdp1.ZData = pos1(:,3);
hdp2.XData = pos2(:,1);
hdp2.YData = pos2(:,2);
hdp2.ZData = pos2(:,3);
hdp3.XData = pos3(:,1);
hdp3.YData = pos3(:,2);
hdp3.ZData = pos3(:,3);
% Draw our plots
drawnow;
end

Categories

Find more on Graphics Performance in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!