从程序创建单个动画

时间:2018-03-09 22:41:19

标签: python animation matplotlib

这个程序用方形补丁填充数字。设置y轴限制,以便可以看出在一个位置只有一个贴片。它描绘了这个灌装过程。我想将填充记录为动画,并尝试使用'matplotlib.animation'。我将程序的绘图部分转换为函数(def filler(b):),以便我可以将此函数传递给底部的动画行。当我运行该程序时,我在绘图结束时发现错误,说Python已停止工作。请有人解释原因。感谢。

请注意,我不知道函数参数中的b代表什么。我把它包括在内,因为没有它,程序就不会运行,要求进行位置参数。

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

startx = 0
endx = 10
blocks = 100
points = np.random.randint(startx,endx,size=blocks)
y = [-1]*int(endx-startx)
fig = plt.figure(figsize=(5,6))
ax = fig.add_subplot(111,aspect='equal')
ax.set_xlim(startx,endx)
ax.set_ylim(0,5)

def filler(b):

    for i in range(blocks):
        z = 5
        a = patches.Rectangle((points[i],z),1,1,ec='k',fc=(1-i/blocks,i/(2*blocks),i/blocks))
        ax.add_patch(a)  
        while z>y[int(points[i])]+1:
            z=z-1
            plt.pause(0.001)
            a.set_y(z)
        y[int(points[i])]=z

filler_ani = animation.FuncAnimation(fig, filler,interval=50, repeat=False, blit=True)
filler_ani.save('filler.mp4')

1 个答案:

答案 0 :(得分:0)

问题中的代码混合了两种不同类型的动画。使用循环plt.draw()FuncAnimation。这将导致混乱,因为基本上屏幕上的完整动画是在FuncAnimation的第一帧期间完成的,在第一帧结束时动画失败。

所以,必须要做出决定。既然你想在这里做一个FuncAnimation,为了能够保存它,你需要摆脱plt.draw。然后问题是有一个for循环和一个while循环。这使得很难使用基于帧编号的动画 相反,可以使用基于生成器的动画。

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

startx = 0
endx = 10
blocks = 101
points = np.random.randint(startx,endx,size=blocks)
y = [-1]*int(endx-startx)

fig = plt.figure(figsize=(5,6))
ax = fig.add_subplot(111,aspect='equal')
ax.set_xlim(startx,endx)
ax.set_ylim(0,5)

def filler():
    yield None
    for i in range(blocks):
        z = 5
        a = patches.Rectangle((points[i],z),1,1,ec='k',fc="r")
        ax.add_patch(a) 
        while z>y[int(points[i])]+1:
            z=z-1
            a.set_y(z)
            yield a
        y[int(points[i])]=z

filler_ani = animation.FuncAnimation(fig, lambda x: None, frames=filler, 
                                     interval=50, blit=False, repeat=False)
plt.show()

这有点像hacky,但最接近你的初始代码。