单独初始化和显示绘图

Separate initialization and display of plot

在 Matlab 中将绘图的初始化和显示分开的正确方法是什么? (我指的是广义上的 plots;可以是 plotplot3scatter 等)举一个具体的例子,我有一个非常复杂的 3D 可视化,它使用 spheremesh 绘制静态球体网格,然后 scatter3 在球体上绘制移动轨迹。为了能够实时执行此操作,我实施了一些简单的优化,例如每帧仅更新 scatter3 对象。但是代码有点乱,很难添加我想要的额外功能,所以我想改进代码分离。

我还觉得 return 函数中的某种绘图对象而不显示它有时可能很有用,例如以一种很好的模块化方式将其与其他绘图组合。

我想到的例子是这样的:

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

每个步骤也可以作为一个函数分离出来。

那么,做这样的事情的一种巧妙而正确的方法是什么?所有文档似乎都假设一个人想要立即显示所有内容。

例如

% 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

基本上您可以更新图形句柄的所有值,在本例中为 'p' 和 's'。如果您打开 plot or plot3 you will find a link to all properties of that primitive: e.g. Line Properties 的 matlab 文档。 scatter/imagesc

存在类似的文档页面

所以一般的想法是首先用第一帧创建一个图形,保存你想要更新的对象的句柄 (p = plot(...),然后进入一个循环,在这个循环中你更新所需的该图形对象的 属性(例如 p.Color = 'r'p.XData = ...)。