如何在MATLAB中加速非常慢的动画情节 [英] How to speed up a very slow animated plot in 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屋!