从程序创建单个动画



这个程序用方形补丁填充了一个数字。设置 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')

问题中的代码混合了两种不同类型的动画。使用循环和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()

这有点笨拙,但最接近您的初始代码。

最新更新