Python matplotlib imshow、ArtistAnimation和class属性

Python matplotlib imshow、ArtistAnimation和class属性,python,animation,matplotlib,Python,Animation,Matplotlib,我试图用Python编写一个康威的生命游戏,并展示其演变过程。我无法显示输出。我已将我的全部代码粘贴到下面 我将此示例用作基础:。我的动画是静态的,但是如果我使用 ims.append([plt.imshow(world.state+0, cmap=plt.cm.binary, interpolation='nearest')]) 它可以正确地设置动画。我试图编写一个函数world.get_state(),认为这是某种计算问题,但没有成功 这让我发疯,我在这里错过了什么 谢谢 impo

我试图用Python编写一个康威的生命游戏,并展示其演变过程。我无法显示输出。我已将我的全部代码粘贴到下面

我将此示例用作基础:。我的动画是静态的,但是如果我使用

ims.append([plt.imshow(world.state+0, cmap=plt.cm.binary, interpolation='nearest')])
它可以正确地设置动画。我试图编写一个函数world.get_state(),认为这是某种计算问题,但没有成功

这让我发疯,我在这里错过了什么

谢谢

    import numpy as np
    from scipy.signal import convolve2d

    import matplotlib.pyplot as plt
    import matplotlib.animation as animation


    class World():
       """world information"""

       def __init__(self, grid):
           # noinspection PyNoneFunctionAssignment
           self.state = np.empty(grid.shape)
           self.__x_size = len(grid[0, :])
           self.__y_size = len(grid[:, 0])
           self.__x = range(self.__x_size)
           self.__y = range(self.__y_size)
           for i in self.__x:
            for j in self.__y:
                self.state[i, j] = grid[i, j]

    def evolve(self):
        alive_neighbours = convolve2d(self.state, np.ones((3, 3)), mode='same', boundary='wrap') - self.state
        for i in self.__y:
            for j in self.__x:
                if alive_neighbours[i, j] < 2:
                    self.state[i, j] = 0
                elif alive_neighbours[i, j] == 3:
                    self.state[i, j] = 1
                elif alive_neighbours[i, j] > 3:
                    self.state[i, j] = 0
        # self.state = np.random.randint(2, size=(self.__x_size, self.__y_size ))


if __name__ == "__main__":
    nbx = 5
    nby = 5
    nb_gen = 5

    initial_seed = np.random.randint(2, size=(nbx, nby))
    world = World(initial_seed)

    ims = []
    fig = plt.figure()

    for i in range(nb_gen):
        ims.append([plt.imshow(world.state, cmap=plt.cm.binary, interpolation='nearest')])
        world.evolve()

    ani = animation.ArtistAnimation(fig, ims, interval=500, blit=True, repeat_delay=1000)

    plt.show()

但这不是我想要的。

动画的每一帧都显示相同的世界状态

由于世界类只修改状态,因此对同一对象的引用将被传递到每个帧的imshow()中。动画的每一帧都引用同一阵列

Matplotlib在调用plt.show()之前不会将动画绘制到屏幕上,因此只能看到传递到imshow()的数组的最终版本,即World.state的最终版本

这与

a = [1, 2, 3]
b = a
a.append(4)
print(b)
输出[1,2,3,4]。b指向a,所以当a改变时,b改变

复制要显示的图像可以解决此问题

ims.append([plt.imshow(world.state.copy(), cmap=plt.cm.binary, interpolation='nearest')])

这也是world.state+0和np.random.randint(2,size=(self.\uuux\u size,self.\uuu y\u size))起作用的原因:它们都创建新数组,并且不修改已经传递到imshow()中的数组。

动画的每一帧都显示相同的世界状态

由于世界类只修改状态,因此对同一对象的引用将被传递到每个帧的imshow()中。动画的每一帧都引用同一阵列

Matplotlib在调用plt.show()之前不会将动画绘制到屏幕上,因此只能看到传递到imshow()的数组的最终版本,即World.state的最终版本

这与

a = [1, 2, 3]
b = a
a.append(4)
print(b)
输出[1,2,3,4]。b指向a,所以当a改变时,b改变

复制要显示的图像可以解决此问题

ims.append([plt.imshow(world.state.copy(), cmap=plt.cm.binary, interpolation='nearest')])

这也是world.state+0和np.random.randint(2,size=(self.\uu x\u size,self.\uu y\u size))起作用的原因:它们都创建了新的数组,并且不修改已经传递到imshow()中的数组。

您好,谢谢您的回答。我不确定我是否理解,因为对象被修改了,对吗?此外,如果在函数evolve中我取消注释行“self.state=np.random.randint(2,size=(self.\uuux\u size,self.\uuu y\u size)),那么它是动画的,根据你所说,它仍然是同一个对象。据我所知,np.random.randint(2,size=(self.\uuux\u size,self.\uu y\u size))创建了一个新数组,这意味着每一帧都会传递一个新对象。嗨,谢谢你的回答。我不确定我是否理解,因为对象被修改了,对吗?此外,如果在函数evolve中我取消注释行“self.state=np.random.randint(2,size=(self.\uuux\u size,self.\uuu y\u size)),那么它是动画的,根据你所说,它仍然是同一个对象。据我所知,np.random.randint(2,size=(self.\uuux\u size,self.\uu y\u size))创建了一个新数组,这意味着在每一帧中都会传递一个新对象。