Python Matplotlib:PatchCollection动画不会更新

时间:2017-08-30 21:09:22

标签: python animation matplotlib

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

根据几个消息来源,可以通过使用PatchCollection而不是循环补丁来加速此过程。这是我的尝试:

class PatientRecordJson:
    def __init__(self):
        self.json = {}

    def set_raw_data_field(self, string):
        self.json['raw_data'] = string

    def get_raw_data_field(self):
        return self.json.get('raw_data', None)

    def set_data_type(self, string):
        self.json['data_type'] = string

    def get_data_type(self):
        return self.json.get('data_type', None)

    def set_type_of_record(self, string):
        self.json['type_of_record'] = string

    def get_type_of_record(self):
        return self.json.get('type_of_record', None)

    def set_npi(self, string):
        self.json['npi'] = string

    def get_npi(self):
        return self.json.get('npi', None)

动画永远不会更新。它被冻结在一块空地上。

我会对其他优化方法持开放态度。当前的解决方案似乎非常冗长,因为每帧只添加一个矩形。

1 个答案:

答案 0 :(得分:2)

我不确定我是否完全理解您的代码。将矩形的facecolor从白色切换为黑色的想法是"添加"那个矩形到情节?

我花了一些时间来弄清楚你的代码无法正常工作的原因,但事实证明这是一个愚蠢的错误。问题在于行ax.add_patch(patch)。实际上,您在绘图中添加了两组矩形,一次作为单个Rectangle实例,另一组作为PatchCollection的一部分。似乎Rectangles保持在集合的顶部,因此你只是没有看到动画。只是评论有问题的行(ax.add_patch(patch))似乎可以解决问题。

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

这里我将如何编写代码(loosely inspired by this question on SO):

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)

enter image description here