如何在MATLAB中加速非常慢的动画情节 [英] How to speed up a very slow animated plot in MATLAB

查看:983
本文介绍了如何在MATLAB中加速非常慢的动画情节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个动画情节,但是我的代码非常慢,也许我使用的方法太幼稚了.在下面的示例中,我有4个子图,每个子图有3行,并在时间"循环中进行了更新.

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.

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

分析器输出中可以看出,drawnow正在杀死时间.有什么方法可以使我更高效地创建此动画?

As can be seen from the profiler output, the drawnow is killing the time. Is there any way I can be more efficient in creating this animation?

推荐答案

由于您需要动画,因此无法使用drawnow更新框架.但是,不是特别使drawnow慢下来的原因-探查器可能会产生误导作用... drawnow只是更新自上次重绘以来的所有图形更改,在您的情况下为十几个新图!

Because you want an animation, there is no alternative to using drawnow to update the frame. 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!

您会发现hold相当慢.例如,如果您比较明智地持有股票,请删除现有的hold on,仅在实际绘图时才持有

You'll find that hold is pretty slowing. For instance if you're wiser about your holding, remove the existing hold on and only hold when actually plotting

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

这可以节省大约10%的时间(从12.3秒降低到11.3秒).

This saves ~10% time on my PC (12.3sec down to 11.3sec).

真正的加速来自完全删除hold以及所有单个plot调用!此方法也不会影响行格式,这将有助于提高速度.在此处.

The real speed up comes from removing hold entirely, along with all of the individual plot calls! This method also doesn't touch the line formatting which will help with speed. See a previous question about updating plot data here.

仅更新绘图数据,而不添加绘图.这使我的速度提高了约68%(从12.3秒降低到4.0秒).

Simply update the plot data instead of adding plots. This gives me a speedup of ~68% (12.3sec down to 4.0sec).

% ... 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    

现在,绘图已经非常优化.如果您希望动画更快甚至更快,请使用for k = 2:n:maxT绘制每个第二,第三,...,第n个时间步长,而不是每个时间步长.

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.

这篇关于如何在MATLAB中加速非常慢的动画情节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆