如何在 MATLAB 中有效地制作动画图?
How to efficiently animate plots in MATLAB?
我在下面写了一个简单的代码来制作动画图,但它们往往需要大量的计算,比预期的要长整整几秒:
function animplot(t,f,ymin,ymax,dt,num_iters)
h = plot(0,0); % set initial handle for first iteration
tic % start timer
for i=2:num_iters
delete(h);
h = plot(t,f(t-dt*i),'LineWidth',2,'color','b');
axis([min(t) max(t) ymin ymax]); pause(1/num_iters)
end
toc % end timer, return time elapsed since 'tic'
end
将 1/num_iters
替换为 dT = T / num_iters
,并设置 T = 1
,1000 次迭代的计算时间为 6 秒以上(而不是 1 秒)。 Sample animation 对于 t = 0:.01:2*pi; f = @(t)sin(t); dt = .05; num_iters = 1000
有没有更有效的动画制作方法?
一个明显更有效的代码,根据 related inquiry 中的解决方案进行了调整:
function animplot(t,f,ymin,ymax,dt,num_iters,T)
% ANIMPLOT(t,f,ymin,ymax,dt,num_iters) -- f must be defined w/ handle,
% e.g. f = @(t)sin(t); default T = 5, num_iters = 500, dt = .05,
% (ymax - ymin) = 1.4*range.
switch nargin
case 6; T = 5;
case 5; T = 5; num_iters = 500;
case 4; T = 5; num_iters = 500; dt = .05;
case 2; T = 5; num_iters = 500; dt = .05;
ymin = 1.2*min(f(t)) - max(f(t))/5;
ymax = 1.2*max(f(t)) - min(f(t))/5;
end
dT = T/num_iters; % set pause interval
h = plot(0,0,'LineWidth',2,'color','b'); % set initial handle
set(h, 'Xdata',t, 'Ydata', f(t)); % initialize curve plot
axis([min(t) max(t) ymin ymax]);
tic % start timer
for i=2:num_iters
pause(dT)
set(h, 'Ydata', f(t-dt*i))
end
toc % end timer, return time elapsed since 'tic'
end
注:num_iters
主要作为动画'resolution';更高的代价是与集合 T
.
的偏差更大
使用命令:"set(h, 'Xdata',t, 'Ydata', f(t))" 将比在每次循环迭代中重复使用 plot 函数更有效,并且它本身可能足以实现您正在寻找的结果。为了进一步改进,您可以启用可变帧速率。为此,消除任何 "pause(dt)",获取当前循环迭代的时间 "t",评估该时间的函数 "f(t)" 并将绘图 x 和 y 数据设置为该时间。这将确保动画流畅,不会超过指定的时间。您还可以在数据集上使用此技术,而不仅仅是函数,方法是使用 "interp1(x,v,xq)" 函数在数据点之间进行线性插值。
我在下面写了一个简单的代码来制作动画图,但它们往往需要大量的计算,比预期的要长整整几秒:
function animplot(t,f,ymin,ymax,dt,num_iters)
h = plot(0,0); % set initial handle for first iteration
tic % start timer
for i=2:num_iters
delete(h);
h = plot(t,f(t-dt*i),'LineWidth',2,'color','b');
axis([min(t) max(t) ymin ymax]); pause(1/num_iters)
end
toc % end timer, return time elapsed since 'tic'
end
将 1/num_iters
替换为 dT = T / num_iters
,并设置 T = 1
,1000 次迭代的计算时间为 6 秒以上(而不是 1 秒)。 Sample animation 对于 t = 0:.01:2*pi; f = @(t)sin(t); dt = .05; num_iters = 1000
有没有更有效的动画制作方法?
一个明显更有效的代码,根据 related inquiry 中的解决方案进行了调整:
function animplot(t,f,ymin,ymax,dt,num_iters,T)
% ANIMPLOT(t,f,ymin,ymax,dt,num_iters) -- f must be defined w/ handle,
% e.g. f = @(t)sin(t); default T = 5, num_iters = 500, dt = .05,
% (ymax - ymin) = 1.4*range.
switch nargin
case 6; T = 5;
case 5; T = 5; num_iters = 500;
case 4; T = 5; num_iters = 500; dt = .05;
case 2; T = 5; num_iters = 500; dt = .05;
ymin = 1.2*min(f(t)) - max(f(t))/5;
ymax = 1.2*max(f(t)) - min(f(t))/5;
end
dT = T/num_iters; % set pause interval
h = plot(0,0,'LineWidth',2,'color','b'); % set initial handle
set(h, 'Xdata',t, 'Ydata', f(t)); % initialize curve plot
axis([min(t) max(t) ymin ymax]);
tic % start timer
for i=2:num_iters
pause(dT)
set(h, 'Ydata', f(t-dt*i))
end
toc % end timer, return time elapsed since 'tic'
end
注:num_iters
主要作为动画'resolution';更高的代价是与集合 T
.
使用命令:"set(h, 'Xdata',t, 'Ydata', f(t))" 将比在每次循环迭代中重复使用 plot 函数更有效,并且它本身可能足以实现您正在寻找的结果。为了进一步改进,您可以启用可变帧速率。为此,消除任何 "pause(dt)",获取当前循环迭代的时间 "t",评估该时间的函数 "f(t)" 并将绘图 x 和 y 数据设置为该时间。这将确保动画流畅,不会超过指定的时间。您还可以在数据集上使用此技术,而不仅仅是函数,方法是使用 "interp1(x,v,xq)" 函数在数据点之间进行线性插值。