2020年6月29日月曜日

matplotlibでアニメーション(ライフゲーム)

ライフゲームを表示するスクリプトをmatplotlibのアニメーションで書いたものがこちら。 前のものは、FuncAnimation()へ引き渡す関数をlambda式で作成することで、 フレーム番号以外のパラメータを関数に持たせて受け渡す方法を用いましたが、 Pythonなら、クラスを用いるのもよいです。 クラスにすると、なにかパラメータを保持させていることが明確です。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation

def Rule(alive, neighbours):
    n = sum(neighbours)
    if not alive and n==3:
        return 1 
    if alive and n==2 or n==3:
        return 1 
    if alive and n<=1:
        return 0 
    if alive and n>=4:
        return 0 
    else:
        return alive

def LifeGameUpdate(world, rule):
    w, h = world.shape
    updated_world = np.zeros((w, h))
    for i in range(h):
        for j in range(w):
            im, ip = (i-1) % h, (i+1) % h
            jm, jp = (j-1) % w, (j+1) % w
            neighbours = (
                    world[im, jm], world[im, j], world[im, jp], 
                    world[i, jm], world[i, jp],
                    world[ip, jm], world[ip, j], world[ip, jp])
            updated_world[i, j] = rule(world[i, j], neighbours)
    return updated_world

class LifeGame(object):
    def __init__(self, world, rule):
        self.world = world
        self.rule = rule

    def __call__(self, frame_count):
        plt.cla()
        plt.imshow(self.world)
        self.world = LifeGameUpdate(self.world, self.rule)

if __name__ == '__main__':
    fig = plt.figure()
    world = np.round(np.random.random((100, 100)))
    lifegame = LifeGame(world, Rule)
    anim = matplotlib.animation.FuncAnimation(fig, lifegame, interval=10)
    plt.show()
            

0 件のコメント: