简体   繁体   English

如何在MATLAB中加速非常慢的动画情节

[英]How to speed up a very slow animated plot in MATLAB

I'm trying to create an animated plot but my code is very slow, perhaps the method I'm using is too naive. 我正在尝试创建动画情节,但是我的代码很慢,也许我使用的方法太幼稚了。 In the below example, I have 4 subplots each with 3 lines, which I update in a 'time' loop. 在下面的示例中,我有4个子图,每个子图有3行,并在“时间”循环中进行了更新。

clc;clear;close all;
state = {'$x-Position$','$x-Velocity$','$y-Position$','$y-Velocity$'};
ylabels = {'$x$','$\dot{x}$','$y$','$\dot{y}$'};
options1 = {'interpreter','latex'};
options2 = {'interpreter','latex','fontsize',20};
maxT = 300;

for pp = 1:4
    hh1(pp)=subplot(2,2,pp);
    xlabel('$t$',options2{:});
    ylabel(ylabels{pp},options2{:});
    title(state{pp},options1{:})
    xlim([0 maxT])
    hold on
end
x = randn(4,300);
z = randn(4,300);
x_est = randn(4,300);
for k = 2:maxT
    for p = 1:4
        plot(hh1(p),k-1:k,x(p,k-1:k),'b','linewidth',2)
        plot(hh1(p),k-1:k,z(p,k-1:k),'m')
        plot(hh1(p),k-1:k,x_est(p,k-1:k),':k','linewidth',2)
    end
    drawnow;
end

As can be seen from the profiler output , the drawnow is killing the time. 探查器输出中可以看出, drawnow正在浪费时间。 Is there any way I can be more efficient in creating this animation? 有什么方法可以使我更有效地创建此动画?

Because you want an animation, there is no alternative to using drawnow to update the frame. 因为您需要动画,所以没有其他方法可以使用drawnow更新框架。 However, it's not drawnow in particular which is slowing you down - the profiler can be misleading... drawnow simply updates all of the graphics changes since the last re-draw, which in your case is a dozen new plots! 但是, drawnow速度并不是特别慢,它会拖慢您的速度-探查器可能会产生误导作用... drawnow只是更新自上次重新绘制以来的所有图形更改,在您的情况下,这是drawnow新绘图!

You'll find that hold is pretty slowing. 你会发现, hold是相当缓慢。 For instance if you're wiser about your holding, remove the existing hold on and only hold when actually plotting 举例来说,如果你对你持有聪明,删除现有的hold on ,只有实际打印时举行

% ... above code the same but without 'hold on'
for p = 1:4
    hold(hh1(p), 'on');
    % plots
    hold(hh1(p), 'off');
end

This saves ~10% time on my PC (12.3sec down to 11.3sec). 这样可以在我的PC上节省约10%的时间(从12.3秒降低到11.3秒)。


The real speed up comes from removing hold entirely, along with all of the individual plot calls! 真正的加速来自于完全取消hold ,以及所有单独的plot调用! This method also doesn't touch the line formatting which will help with speed. 此方法也不会影响行格式,这将有助于提高速度。 See a previous question about updating plot data here . 在此处查看有关更新绘图数据的先前问题。

Simply update the plot data instead of adding plots . 只需更新绘图数据,而不添加绘图即可 This gives me a speedup of ~68% (12.3sec down to 4.0sec). 这使我的速度提高了约68%(从12.3秒降低到4.0秒)。

% ... your same setup
% Initialise plot data
x = randn(4,300);
z = randn(4,300);
x_est = randn(4,300);
plts = cell(4,3);
hh1 = cell(4,1);

% Loop over subplots and initialise plot lines
for p = 1:4
    hh1{p}=subplot(2,2,p);
    xlabel('$t$',options2{:});
    ylabel(ylabels{p},options2{:});
    title(state{p},options1{:})
    xlim([0 maxT])
    % Hold on to make 3 plots. Create initial points and set line styles.
    % Store the plots in a cell array for later reference.
    hold on
    plts{p,1} = plot(hh1{p},1:2,x(p,1:2),'b','linewidth',2);
    plts{p,2} = plot(hh1{p},1:2,z(p,1:2),'m');
    plts{p,3} = plot(hh1{p},1:2,x_est(p,1:2),':k','linewidth',2);
    hold off
end
% March through time. No replotting required, just update XData and YData
for k = 2:maxT
    for p = 1:4
        set(plts{p,1}, 'XData', 1:k, 'YData', x(p,1:k) );
        set(plts{p,2}, 'XData', 1:k, 'YData', z(p,1:k) );
        set(plts{p,3}, 'XData', 1:k, 'YData', x_est(p,1:k) );
    end
    drawnow;
end    

Now the plotting is pretty optimised. 现在,绘图已相当优化。 If you want the animation to be even quicker then just plot every 2nd, 3rd, ..., nth timestep instead of every timestep by using for k = 2:n:maxT . 如果您希望动画更快,则只需使用for k = 2:n:maxT绘制每个第二,第三,...,第n个时间步长而不是每个时间步长for k = 2:n:maxT

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM