デジタル・デザイン・ラボラトリーな日々

アラフィフプログラマーが数学と物理を基礎からやり直す。https://qiita.com/yaju

Google Colaboratory上でmatplotlibのアニメーションを再生する

はじめに

最近は、Anacodaを使わずにGoogle Colaboratoryを使用しています。
Google ChromでGoogle Colaboratory にアクセスすれば、すぐにPythonが使えますからね。

下記サイトでは勾配降下法 (Gradient Descent)のグラフをアニメーション化しており、かっこいいです。
sinhrks.hatenablog.com

Google Colaboratory でPython 3に変更して動かして見たのですが、アニメーションは動きませんでした。

アニメーション

下記サイトを参考に Jupyter notebookと同じようにmatplotlibのnbagg を有効にしてみたりしたのですが、駄目でした。 qiita.com

ネットの検索条件「Google Colaboratory animation」と英語化して、見つけたのが下記サイトとなります。 medium.com

技術的なことは、下記サイトが参考になります。
「JupiterにMatplotlibアニメーションをインタラクティブJavaScriptウィジェットとして埋め込む」
louistiao.me

下記プログラムをGoogle Colaboratoryに貼り付けると、アニメーションが表示されます。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from IPython.display import HTML
# animate over some set of x, y
x = np.linspace(-4, 4, 100)
y = np.sin(x)
# First set up the figure, the axes, and the plot element
fig, ax = plt.subplots()
plt.close()
ax.set_xlim(( -4, 4))
ax.set_ylim((-2, 2))
line1, = ax.plot([], [], lw=2)
line2, = ax.plot([], [], lw=2)
# initialization function: plot the background of each frame
def init():
    line1.set_data(x, y)      
    return (line1,)
# animation function: this is called sequentially
def animate(i):
  at_x = x[i]
  
  # gradient_line will have the form m*x + b
  m = np.cos(at_x)
  b = np.sin(at_x) - np.cos(at_x)*at_x
  gradient_line = m*x + b
  
  line2.set_data(x, gradient_line)
  return (line2,)
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=100, blit=True)
rc('animation', html='jshtml')
anim

f:id:Yaju3D:20180731234424g:plain

アニメーションの保存

下記サイトを見つけました。 qiita.com

Google Colaboratory上ではどうすれば出来るのかを検討したところ、mp4形式なら出来ることが分かりました。 参照:Sum approximation

準備として、ffmpeg をインストールする必要があります。

# To make an animation, we need ffmpeg
!apt-get update && apt-get install ffmpeg

先程のプログラムの下側にあるコードを変更します。

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=100, blit=True)

# add code
plt.rcParams['animation.ffmpeg_path'] = '/usr/bin/ffmpeg' # For google colab
HTML(ani.to_html5_video())

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

表示された動画にある「︙」をクリックすれば、ダウンロード出来ます。
※下図はキャプチャした静止画です。
f:id:Yaju3D:20180812130117p:plain

Twitterは動画形式のmp4対応しているので、ツイートする分には問題ありません。
どうしてもgifにしたい場合には、オンライン上でmp4からgifに変換できます。
www.aconvert.com

gif保存には調査が必要

上記方法より先にgif形式を試したのですが、PillowWriterでインポートエラーになりました。
もしかしたら出来る方法があるかも知れませんが、追求はやめました。

from matplotlib.animation import PillowWriter

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=100, blit=True)
anim.save("gradientline.gif", writer=PillowWriter(fps=60))

#ImportError: cannot import name 'PillowWriter'

最後に

後で、勾配降下法 (Gradient Descent)のグラフをアニメーション化して公開する予定です。
今回は紹介まで。