alifelab / alife_book_src

「作って動かすALife - 実装を通した人工生命モデル理論入門」サンプルコード
235 stars 114 forks source link

サンプルプログラムをColaboratoryで動かしたい #28

Closed zhikto closed 1 year ago

zhikto commented 5 years ago

githubのディレクトリをColaboratory上にて!git clone https://github.com/alifelab/alife_book_srcで呼び出して、%run -i alife_book_src/chap02/gray_scott.pyで実行させようと試みているんですが、以下のようなエラーが出てしまいます。Colaboratory上で実行された方が居ましたら、是非ご教授願いたいです。 ※一応エラーの通りにPyQt5はインストールしましたが、同様なエラーが出ます。

`--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) /content/alife_book_src/alife_book_src/chap02/gray_scott.py in () 5 sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定 6 import numpy as np ----> 7 from alifebook_lib.visualizers import MatrixVisualizer 8 9 # visualizerの初期化 (Appendix参照)

/content/alife_book_src/alifebook_lib/init.py in () 1 import vispy ----> 2 vispy.use('PyQt5')

/usr/local/lib/python3.6/dist-packages/vispy/util/wrappers.py in use(app, gl) 94 if app: 95 from ..app import use_app ---> 96 use_app(app) 97 98

/usr/local/lib/python3.6/dist-packages/vispy/app/_default_app.py in use_app(backend_name, call_reuse) 45 46 # Create default app ---> 47 default_app = Application(backend_name) 48 return default_app 49

/usr/local/lib/python3.6/dist-packages/vispy/app/application.py in init(self, backend_name) 47 self._backend_module = None 48 self._backend = None ---> 49 self._use(backend_name) 50 51 def repr(self):

/usr/local/lib/python3.6/dist-packages/vispy/app/application.py in _use(self, backend_name) 221 if not try_others: 222 # Fail if user wanted to use a specific backend --> 223 raise RuntimeError(msg) 224 elif key in imported_toolkits: 225 # Warn if were unable to use an already imported toolkit

RuntimeError: Could not import backend "PyQt5": No module named 'PyQt5'`

mitsuyoshi-yamazaki commented 5 years ago

Colaboratory上ではPyQtが動作せず、vispyのWebGL backendはまだ完成していないようで利用できませんでしたが、matplotlibを利用して alifebook_lib.visualizer に相当する描画部分を置き換えることでColaboratory上で動作させることができました。

# alife_book_src/chap02/gray_scott.py を編集
import sys, os
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.animation as animation
from matplotlib import rc

# シミュレーションの各パラメタ
SPACE_GRID_SIZE = 256
dx = 0.01
dt = 1
VISUALIZATION_STEP = 64  # 何ステップごとに画面を更新するか。 # どうもimshowの実行が遅いので数値を大きくしている

# モデルの各パラメタ
Du = 2e-5
Dv = 1e-5
f, k = 0.04, 0.06  # amorphous
# f, k = 0.035, 0.065  # spots
# f, k = 0.012, 0.05  # wandering bubbles
# f, k = 0.025, 0.05  # waves
# f, k = 0.022, 0.051 # stripe

# 初期化
u = np.ones((SPACE_GRID_SIZE, SPACE_GRID_SIZE))
v = np.zeros((SPACE_GRID_SIZE, SPACE_GRID_SIZE))
# 中央にSQUARE_SIZE四方の正方形を置く
SQUARE_SIZE = 20
u[SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2,
  SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2] = 0.5
v[SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2,
  SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2] = 0.25
# 対称性を壊すために、少しノイズを入れる
u += np.random.rand(SPACE_GRID_SIZE, SPACE_GRID_SIZE)*0.1
v += np.random.rand(SPACE_GRID_SIZE, SPACE_GRID_SIZE)*0.1

value_range_min=0
value_range_max=1

value_range = (value_range_min, value_range_max)

def frames(*args, **kwargs):
  global u, v, value_range
  for i in range(VISUALIZATION_STEP):
    # ラプラシアンの計算
    laplacian_u = (np.roll(u, 1, axis=0) + np.roll(u, -1, axis=0) +
                    np.roll(u, 1, axis=1) + np.roll(u, -1, axis=1) - 4*u) / (dx*dx)
    laplacian_v = (np.roll(v, 1, axis=0) + np.roll(v, -1, axis=0) +
                    np.roll(v, 1, axis=1) + np.roll(v, -1, axis=1) - 4*v) / (dx*dx)
    # Gray-Scottモデル方程式
    dudt = Du*laplacian_u - u*v*v + f*(1.0-u)
    dvdt = Dv*laplacian_v + u*v*v - (f+k)*v
    u += dt * dudt
    v += dt * dvdt
    matrix = u
    matrix[matrix < value_range[0]] = value_range[0]
    matrix[matrix > value_range[1]] = value_range[1]
  img = ((matrix.astype(np.float64) - value_range[0]) / (value_range[1] - value_range[0]) * 255).astype(np.uint8)
  return [plt.imshow(img, interpolation='none')]

fig = plt.figure()
anim = animation.FuncAnimation(fig, frames, frames=120, interval=200) # 計算し終わるまで時間がかかります

rc('animation', html='jshtml')

anim

変更がvisualizerの差し替えのみで済めば全てのサンプルをmatplotlibで(= Colaboratory上で)動かせたのですが、visualizerと matplotlib.animation のインターフェース構造が異なっていたのでサンプルごとに書き換えないと動かなそうです 😞