matplotlib.animationでグラフをアニメーションさせる

# matplotlib.animationとは


値やデザインを変えたグラフを連続して描画することでアニメーションさせるmatplotlibの機能です。gif画像や動画ファイルで書き出したりhtml + JavaScriptで書き出すことも出来るので二次利用もやりやすいと思います。


# 1. インストール


matplotlibをインストールするだけです

```terminal:terminal
pip install matplotlib
```


# 2. 2つのクラス

2つのクラスから選べます

<b>matplotlib.animation.ArtistAnimation</b>
描画情報のlistを作って描画するクラスです

<b>matplotlib.animation.FuncAnimation</b>
描画情報を更新する関数を渡して逐次実行で描画するクラスです
乱数を使って毎回違うグラフを描画するような使い方が出来ます


# 3. 使い方


## 3-1. terminal実行で使う

こちらのコードをお借りしてやってみます
https://qiita.com/yubais/items/c95ba9ff1b23dd33fde2


### 1. ArtistAnimationの場合


plt.plot()などで作った描画分のオブジェクトをlistにしてArtistAnimationに放り込んでやるとアニメーション描画をやってくれます。ArtistAnimationでは先に描画情報を作っておいてから放り込むので繰り返しパターンは同じになります。


```python:artist_animation.py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()

ims = []

for i in range(10):
    rand = np.random.randn(100)
    im = plt.plot(rand)
    ims.append(im)

ani = animation.ArtistAnimation(fig, ims, interval=100)
plt.show()
```
terminalからpython artist_animation.pyを実行するとこんな感じのが表示される筈です
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/676392a2-d414-956f-a2c4-a4763453e4c2.gif" width=50%>


### 2. FuncAnimationの場合


listにして放り込むのは同じですが描画する関数を
定義して渡すことで毎回違う乱数を表示出来ます


```python:func_animation.py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()

def plot(data):
    plt.cla()
    rand = np.random.randn(100)
    im = plt.plot(rand)

ani = animation.FuncAnimation(fig, plot, interval=100)
plt.show()
```


terminalからpython func_animation.pyを実行するとこんな感じのが表示される筈です。下に貼っているのは後で説明するやり方で書き出したgif画像なので同じパターンの繰り返しになっていますが、pythonが表示してくれるwindowの方はちゃんと乱数を作り直して毎回違うパターンを表示してくれる筈です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/4c6351cd-ec5e-8246-84f4-65a3a1a8c0c8.gif" width=50%>
なお、上記ではplt.cla()しているので軸が毎回作り直されていますが、変わらないように書くことも出来ます。


## 3-2. gif画像で保存する


animationオブジェクトのsaveメソッドを使えば保存できます


```python:func_animation.pyに1行書き足す
ani.save('func_animation.gif', writer='pillow')
```

writerクラスとしてはPillow、FFMpeg、ImageMagickなどが選べますが、pipで簡単にインストール出来るPillowが手軽だと思います。


## 3-3. jupyter notebookに表示する


上記のplt.show()で表示するやり方はjupyter notebookでは出来ないようですが、gif画像を書き出してから表示するか、Javascript htmlに変換してIPython.display.HTMLに表示してもらう事で表示できます。またh264 encoderがある環境なら動画に変換してIPython.display.HTMLで表示するやり方も使えるようです。
https://qiita.com/fhiyo/items/0ea94b0de6cd5c76d67a


### 1. gif画像を書き出して表示する


```python:jupyter_notebook
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import Image

fig = plt.figure()

ims = []

for i in range(10):
    rand = np.random.randn(100)
    im = plt.plot(rand)
    ims.append(im)

ani = animation.ArtistAnimation(fig, ims, interval=100)
ani.save('../artist_animation.gif', writer='pillow')
plt.close()

Image('../artist_animation.gif')
```


### 2. Javascript htmlに変換して表示する


to_jshtml()メソッドを使うとhtml + Javascriptに変換してくれます


```python:jupyter_notebook
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML

fig = plt.figure()

ims = []

for i in range(10):
    rand = np.random.randn(100)
    im = plt.plot(rand)
    ims.append(im)

ani = animation.ArtistAnimation(fig, ims, interval=100)
plt.close()

HTML(ani.to_jshtml())
```


FuncAnimationで書きたい場合は以下のようにします


```python:jupyter_notebook
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML

fig = plt.figure()

N = 100
rand = np.random.randn(N)
im, = plt.plot(rand)
    
def update(frame):
    x = np.arange(N)
    y = np.random.randn(N)
    im.set_data(x, y)

ani = animation.FuncAnimation(fig, update, interval=100)
plt.close()

HTML(ani.to_jshtml())
```


# 4. FuncAnimationとArtistAnimationの使い分け


FuncAnimationで書いても、gif画像書き出しやJavascriptでの書き出しはひと回し生成したところまでの情報での書き出しになので乱数を繰り返し生成するというのは出来ません。実行時間はFuncAnimationで書いた方が掛かりますので、jupyter notebookで使う場合はFuncAnimationで書く意味はあまりないと思います。