home about terms twitter

(Python)Google Colabでライフゲームをmp4出力

date: 2021-05-31 | mod: 2021-05-31

前書き

本記事のプログラムでは、Google Colabolatory上でPythonによるライフゲームを実行します。 得られる出力をmp4動画としてGoogleドライブ上に保存します。

ライフゲーム(Conway’s Game of Life)について詳しくは以下の記事をご参照ください。 以下の記事ではgifによる出力を行っています。

方法

以下ではPython, numpy, matplotlibを用いた、Google Colaboratory上でのライフゲームの作り方について一例を示します。

プログラムの流れは以下の通りです。

  • プロットの設定
  • X, Yの範囲を指定
  • Zとしてランダムな整数値を用意
  • 以下をフレーム数分ループ
    • 次世代としてZをコピー
    • pcolormeshとしてプロット
    • 次世代のZについてイベント処理
  • アニメーションとして書き出す
  • mp4ファイルとしてセーブ

作業前にドライブをマウントします。

from google.colab import drive
drive.mount('/gdrive')

実行後に得られるURLからページを進んでいき、許可するためのキーを取得してボックスに貼り付けます。

結果

matplotlibではColormapsとしてカラーバリエーションが選べます(参考:Choosing Colormaps in Matplotlib — Matplotlib 3.4.2 documentation)。

# two species, multiple colors, mp4
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation as fca

fig, axs = plt.subplots(2, 2, figsize=(3, 3))
axs[0, 0].axis("off")
axs[0, 1].axis("off")
axs[1, 0].axis("off")
axs[1, 1].axis("off")

X, Y    = np.mgrid[0:51, 0:51]
Z       = np.random.randint(0, 2, X.shape)

def plot(frame): 
    Zn = Z # 次世代(Zのコピー)
    mesh = axs[0, 0].pcolormesh(X, Y, Zn, cmap="inferno")
    mesh = axs[0, 1].pcolormesh(X, Y, Zn, cmap="viridis")
    mesh = axs[1, 0].pcolormesh(X, Y, Zn, cmap="cividis")
    mesh = axs[1, 1].pcolormesh(X, Y, Zn, cmap="gnuplot")
    for i in range(len(Z)): # 行数ループ
        if i == len(Z)-1: continue #プロット端はスキップ
        else:
            for j in range(len(Z)): # 列数ループ
                if (j == len(Z)-1): continue #プロット端はスキップ
                sr = (Z[i-1, j-1] + Z[i-1, j] + Z[i-1, j+1] +
                      Z[i, j-1]               + Z[i, j+1]   +
                      Z[i+1, j-1] + Z[i+1, j] + Z[i+1, j+1]) # surround cell sum
                nc =  Z[i, j] # now cell
                if   (sr ==  2 and nc == 0): Zn[i, j] = 1 # 誕生
                elif (sr ==  3 and nc == 0): Zn[i, j] = 1
                elif (sr ==  6 and nc == 1): Zn[i, j] = 2 # 変異
                elif (sr ==  8 and nc == 1): Zn[i, j] = 2
                elif (sr == 10 and nc == 1): Zn[i, j] = 2
                elif (sr <=  3 and nc == 1): Zn[i, j] = 0 # 過疎
                elif (sr <=  6 and nc == 2): Zn[i, j] = 0
                elif (sr >= 10 and nc == 1): Zn[i, j] = 0 # 過密
                elif (sr >= 12 and nc == 2): Zn[i, j] = 0
                else: pass

a = fca(fig, plot, frames=500)
a.save("/gdrive/My Drive/lg_one-species.mp4", writer="ffmpeg", fps=10)

今回は以下の配置で4種のカラーマップを試しました。

inferno viridis
cividis gnuplot

最後の三行でプロットや出力ファイルの設定を行っています。 ffmpegを指定することでビデオファイルの編集が可能となります。

今回の設定では、

  • frames = 500
  • fps = 10

なので50秒の動画が出来上がります。

Youtubeに投稿してみました。

画質に関しては改善の余地があります。

関連記事