Python动画:大量数据,慢速动画

时间:2018-11-10 03:36:22

标签: python animation matplotlib

迭代更新非常慢,每次仅n + = 3,但是我的数据有10000个元素。就像,它尝试更新每个单帧n = 1,n = 2,n = 3 ..但hist函数是真正耗电。我不知道是否有什么方法可以跳过帧,例如从n = 1直接转到n = 500和n = 1000。

import matplotlib.animation as animation
import numpy as np
import matplotlib.pyplot as plt
n=10000
def update(curr):
    if curr==n:
        a.event_source.stop()
    first_histogram.cla()
    sec_histogram.cla()
    thi_histogram.cla()
    for_histogram.cla()  
    first_histogram.hist(x1[:curr], bins=np.arange(-6,2,0.5))
    sec_histogram.hist(x2[:curr], bins=np.arange(-1,15,1))
    thi_histogram.hist(x3[:curr], bins=np.arange(2,22,1))
    for_histogram.hist(x4[:curr], bins=np.arange(13,21,1))
    first_histogram.set_title('n={}'.format(curr))
fig=plt.figure()
gspec=gridspec.GridSpec(2,2)
first_histogram=plt.subplot(gspec[0,0])
sec_histogram=plt.subplot(gspec[0,1])
thi_histogram=plt.subplot(gspec[1,0])
for_histogram=plt.subplot(gspec[1,1])
a = animation.FuncAnimation(fig,update,blit=True,interval=1,repeat=False)

如何使其更快?谢谢!

1 个答案:

答案 0 :(得分:0)

这里有几件事要注意。

blit=True在清除中间的轴时不起作用。这可能不会生效,或者您将在轴上获得错误的刻度标签。 仅在各轴的限制没有变化的情况下才有用。但是,在正常的直方图中,需要对越来越多的数据进行动画处理,这一定是必需的,否则条形图可能会超出轴范围,或者开始时看不到较小的数字。另外,您可以绘制标准化的直方图(即密度图)。

此外,interval=1也没有用。在任何普通系统上,您将无法以1毫秒的帧速率为4个子图制作动画。 Matplotlib太慢了。但是,请考虑,无论如何,人脑通常都无法解析高于25 fps(即40 ms)的帧速率。这可能是针对的帧速率(尽管matplotlib可能无法实现这一目标)

因此,设置方法很简单

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

x1 = np.random.normal(-2.5, 1, 10000)

def update(curr):
    ax.clear()
    ax.hist(x1[:curr], bins=np.arange(-6,2,0.5))
    ax.set_title('n={}'.format(curr))

fig, ax = plt.subplots()
a = animation.FuncAnimation(fig, update, frames=len(x1), interval=40, repeat=False, blit=False)

plt.show()

如果您想更快地到达列表中的最终物品数,请使用较少的相框。例如。要使动画播放速度提高25倍,则每25个状态仅显示一次,

a = animation.FuncAnimation(fig, update, frames=np.arange(0, len(x1)+1, 25),
                            interval=40, repeat=False, blit=False)

此代码以11 fps(约85毫秒的间隔)的帧速率运行,因此它比指定的速度慢,这又意味着我们可以直接设置interval=85

为了提高帧速率,可以使用blitting。 为此,您根本不需要更新轴限制。为了进一步优化,您可以预先计算要显示的所有直方图。但是请注意,轴限制随后不应更改,因此我们在开始时设置它们,从而得出不同的图。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

x1 = np.random.normal(-2.5, 1, 10000)
bins = np.arange(-6,2,0.5)
hist = np.empty((len(x1), len(bins)-1))
for i in range(len(x1)):
    hist[i, :], _ = np.histogram(x1[:i], bins=bins) 

def update(i):
    for bar, y in zip(bars, hist[i,:]):
        bar.set_height(y)
    text.set_text('n={}'.format(i))
    return list(bars) + [text]

fig, ax = plt.subplots()
ax.set_ylim(0,hist.max()*1.05)
bars = ax.bar(bins[:-1], hist[0,:], width=np.diff(bins), align="edge")
text = ax.text(.99,.99, "", ha="right", va="top", transform=ax.transAxes)

ani = animation.FuncAnimation(fig, update, frames=len(x1), interval=1, repeat=False, blit=True)

plt.show()

运行此代码后,我的帧速率为215 fps(每帧4.6毫秒),因此我们可以将interval设置为4.6毫秒。