Python Matplotlib:PatchCollection动画不';t更新

Python Matplotlib:PatchCollection动画不';t更新,python,animation,matplotlib,Python,Animation,Matplotlib,我一直在尝试优化matplotlib动画,其中包括在每次迭代时向绘图中添加一个矩形。由于动画功能会在每次迭代时更新整个面片集,因此对于大面片集来说速度非常慢 根据一些消息来源,通过使用补丁集合而不是在补丁上循环,可以加快这个过程。这是我的尝试: from matplotlib import pyplot from matplotlib import patches from matplotlib import animation from matplotlib.collections impor

我一直在尝试优化matplotlib动画,其中包括在每次迭代时向绘图中添加一个矩形。由于动画功能会在每次迭代时更新整个面片集,因此对于大面片集来说速度非常慢

根据一些消息来源,通过使用补丁集合而不是在补丁上循环,可以加快这个过程。这是我的尝试:

from matplotlib import pyplot
from matplotlib import patches
from matplotlib import animation
from matplotlib.collections import PatchCollection

fig = pyplot.figure()

coords = [[1,0],[0,1],[0,0]] #arbitrary set of coordinates

ax = pyplot.axes(xlim=(0, len(coords)), ylim=(0, len(coords)))
ax.set_aspect('equal')


patchList = list()

for coord in coords:
    patch = patches.Rectangle(coord, 1, 1, color="white")
    ax.add_patch(patch)
    patch.set_visible = True
    patchList.append(patch)

rectangles = PatchCollection(patchList, animated=True)
ax.add_collection(rectangles)


black = []
white = ["white"]*len(patchList)

def animate(i):
    black.append("black")
    white.pop()

    colors = black + white
    print(colors)

    rectangles.set_facecolors(colors)
    print("%.2f%%..."%(100*float(i+1)/len(coords)))

    return rectangles,

anim = animation.FuncAnimation(fig, animate,
                               # init_func=init,
                               frames=len(coords)-1,
                               interval=1,
                               blit=True,
                               repeat = False)

pyplot.show()
动画从不更新。它被冻结在一块空地上


我愿意接受其他优化方法。当前的解决方案似乎非常冗长,只需在每个帧中添加一个矩形。

我不确定我是否完全理解您的代码。将矩形的
facecolor
从白色切换为黑色就是将该矩形“添加”到绘图中吗

我花了一点时间才弄明白为什么你的代码不起作用,但结果证明这是一个愚蠢的错误。问题出在ax.add_patch(patch)行上。实际上,您正在绘图上添加两组矩形,一组作为单个
矩形
实例,另一组作为
补丁集合
的一部分。似乎
矩形
位于集合顶部,因此您无法看到动画。仅仅对有问题的行(
ax.add\u patch(patch)
)进行注释似乎就能解决问题

另外,
FuncAnimation(…,interval=)
ms
表示,因此您可能希望将值增加到更大的值(100ms或1000ms,即1s)以查看动画

下面我将如何编写代码():


我不确定我是否完全理解您的代码。将矩形的
facecolor
从白色切换为黑色就是将该矩形“添加”到绘图中吗

我花了一点时间才弄明白为什么你的代码不起作用,但结果证明这是一个愚蠢的错误。问题出在ax.add_patch(patch)行上。实际上,您正在绘图上添加两组矩形,一组作为单个
矩形
实例,另一组作为
补丁集合
的一部分。似乎
矩形
位于集合顶部,因此您无法看到动画。仅仅对有问题的行(
ax.add\u patch(patch)
)进行注释似乎就能解决问题

另外,
FuncAnimation(…,interval=)
ms
表示,因此您可能希望将值增加到更大的值(100ms或1000ms,即1s)以查看动画

下面我将如何编写代码():


谢谢,这解决了我的问题。这个额外的add_补丁线是我以前使用的方法的一个痕迹,它没有使用PatchCollections类,所以我只是忘记删除它。以前,更新绘图的实际时间是限制因素。我正在制作500-1000个方块的动画,所以我希望它运行得尽可能快。20ms将是一个50fps的动画,这对我的目的是好的。此外,我同意在颜色列表中替换第I个值更有意义。如果你要编写自己的这种风格的动画,你会使用PatchCollections并编辑颜色数组,还是用另一种方式?我没有处理大量元素的动画制作经验。但据我所知,只要你能接受使用
集合
对象的限制,它总是比绘制单个补丁要快,这就解决了我的问题。这个额外的add_补丁线是我以前使用的方法的一个痕迹,它没有使用PatchCollections类,所以我只是忘记删除它。以前,更新绘图的实际时间是限制因素。我正在制作500-1000个方块的动画,所以我希望它运行得尽可能快。20ms将是一个50fps的动画,这对我的目的是好的。此外,我同意在颜色列表中替换第I个值更有意义。如果你要编写自己的这种风格的动画,你会使用PatchCollections并编辑颜色数组,还是用另一种方式?我没有处理大量元素的动画制作经验。但据我所知,只要你能接受使用
集合
对象的限制,它总是比绘制单个补丁更快
Nx = 30
Ny = 20
size = 0.5

colors = ['w']*Nx*Ny

fig, ax = plt.subplots()

rects = []
for i in range(Nx):
    for j in range(Ny):
        rect = plt.Rectangle([i - size / 2, j - size / 2], size, size)
        rects.append(rect)

collection = PatchCollection(rects, animated=True)

ax.add_collection(collection)
ax.autoscale_view(True)

def init():
    # sets all the patches in the collection to white
    collection.set_facecolor(colors)
    return collection,

def animate(i):
    colors[i] = 'k'
    collection.set_facecolors(colors)
    return collection,

ani = FuncAnimation(fig, init_func=init, func=animate, frames=Nx*Ny,
        interval=1e2, blit=True)