Python中的动画条形图

马丁·莫纳特

我想用Python制作一个动画的条形图,并将此动画保存为mp4格式。我的问题是,尽管我使用“ blit = True”来告诉动画,仅绘制了逐帧变化的内容,但已保存的视频叠加中的帧仍然存在。令人惊讶的是,此问题在Python的内置预览中没有发生。这是反映我情况的最低要求:

import matplotlib.pyplot as plt
from matplotlib import animation

def barlist(n): #That's the list of bars I want to display
    C=[]
    for k in range(1,6):
        C.append(1/float(n*k))
    return C

fig=plt.figure()

n=100 #Number of frames

def animate(i):
    x=range(1,6)
    y=barlist(i+1)
    return plt.bar(x,y)

anim=animation.FuncAnimation(fig,animate,repeat=False,blit=True,frames=n,
                             interval=50)
anim.save('barchart_animated_'+str(n)+'.mp4')
plt.show()

我必须承认,我不太确定如何解决此缺陷。我知道条形图没有重叠在框架中的唯一示例是这里(更确切地说,我是指以下链接的第一个答案的代码):

在matplotlib中动态更新条形图

看来我必须以某种方式告诉动画它应该如何使用set_height方法设置每帧在每个帧处的高度。但是正如我所说,我真的不知道上面的示例出了什么问题。谢谢你的帮助!

马丁

认真的重要性

这里的问题是,在动画的每个插入过程中都会创建一个新的barplot。它们将一个接一个地添加到图中,但是由于它们的高度随着时间的推移而缩小,因此看起来好像只有第一个条形存在。

有两种方法可以克服此问题。第一种选择是在绘制新的条形图之前清除轴。但是,这将重新缩放轴极限,然后应将其不断设置为相同的值。

另一种选择是在轴上操纵唯一的条形图,并针对每一帧调整其高度。这在下面的代码中显示。

import matplotlib.pyplot as plt
from matplotlib import animation

def barlist(n): 
    return [1/float(n*k) for k in range(1,6)]

fig=plt.figure()

n=100 #Number of frames
x=range(1,6)
barcollection = plt.bar(x,barlist(1))

def animate(i):
    y=barlist(i+1)
    for i, b in enumerate(barcollection):
        b.set_height(y[i])

anim=animation.FuncAnimation(fig,animate,repeat=False,blit=False,frames=n,
                             interval=100)

anim.save('mymovie.mp4',writer=animation.FFMpegWriter(fps=10))
plt.show()


从评论中回答问题:

划线是一种将图形中所有不变的部分存储为背景的技术。然后,对于每个动画帧,仅重绘变化的部分。这样可以避免从头开始重绘背景,从而可以更快地进行动画处理。涂抹只会影响屏幕上的动画,因为将动画保存到文件不是实时执行的(而且也不需要这样做)。
使用blit=False此处可以使代码更简单,因为我们不需要关心屏幕上的动画和保存的动画之间的差异-它们是相同的。

enumerate函数从枚举序列中同时产生索引和对象。我在这里使用了它,因为这是在同一循环中获得两者的便捷方法。在这里根本不重要,您可以选择执行类似的操作

for i in range(len(barcollection)):
    barcollection[i].set_height(y[i])

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章