Home > OS >  Separate initialization and display of plot
Separate initialization and display of plot

Time:05-09

What is a proper way to separate the initialization and the display of plots in Matlab? (I mean plots in a wide sense here; could be plot, plot3, scatter etc.) To give a concrete example, I have a pretty complex 3D visualization that uses sphere and mesh to draw a static sphere mesh and then scatter3 to plot a moving trajectory on the sphere. To be able to do this in real time I have implemented some simple optimizations, such as only updating the scatter3 object each frame. But the code is a bit messy, making it hard to add additional features that I want, so I would like improve code separation.

Plot of moving trajectory on sphere.

I also feel like it might sometimes be useful to return some kind of plot object from a function without displaying it, for example to combine it with other plots in a nice modular way.

An example of what I have in mind would be something like this:

function frames = spherePlot(solution, options)
    % Initialize sphere mesh and scatter objects, configure properties.
    ...
    
    % Configure axes, maybe figure as well.
    ...
    
    % Draw sphere.
    ...
    
    if options.display
        % Display figure.
    end
    
    for step = 1:solution.length
        % Update scatter object, redraw, save frame.
        % The frames are saved for use with 'movie' or 'VideoWriter'.
    end
end

Each step might also be separated out as a function.

So, what is a neat and proper way to do stuff like this? All documentation seems to assume that one wants to display everything right away.

CodePudding user response:

For example

% some sample data
N = 100;
phi = linspace(-pi, pi, N);
theta = linspace(-pi, pi, N);
f = @(phi, theta) [sin(phi).*cos(theta); sin(phi).*sin(theta); cos(phi)];
data = f(phi, theta);

% init plot
figure(1); clf
plot3(data(1,:), data(2,:), data(3,:)); % plot path, not updated
hold on 
p = plot3([0 data(1,1)], [0 data(2,1)], [0 data(3,1)]); % save handle to graphics objects to update
s = scatter3(data(1,1), data(2,1), data(3,1), 'filled');
axis equal
xlabel('x'); ylabel('y'); zlabel('z');
t = title('first frame'); % also store handle for title or labels to update during animation

% now animate the figure
for k = 1:N
    p.XData = [0 data(1,k)]; % update line data
    p.YData = [0 data(2,k)];
    p.ZData = [0 data(3,k)];

    s.XData = data(1,k); % update scatter data
    s.YData = data(2,k);
    s.ZData = data(3,k);

    t.String = sprintf('frame %i', k); % update title
    
    drawnow % update figure
end

Basically you can update all values for a graphics handle, in this case 'p' and 's'. If you open the matlab doc for plot or plot3 you will find a link to all properties of that primitive: e.g. Line Properties. Similar documentation pages exist for scatter/imagesc etc.

So the general idea is to first create a figure with the first frame, save the handles to the objects you would like to update (p = plot(...), and then enter a loop in which you update the required property of that graphics object (e.g. p.Color = 'r', or p.XData = ...).

  • Related