Watson StudioのJupyter Notebookでアニメーション

# はじめに
最近Watson StudioのJupyter Notebookでアニメーションを表示できることを知ったので、その方法についてメモ書きします。

# 前提

* IBM Cloudでのアカウント登録
* Watson Studioのインスタンス作成
* Watson Studioのプロジェクト作成

までは済んでいることを前提とします。手順については、別途[記事](https://qiita.com/makaishi2/items/b666f847a98c2e42dfbb#_reference-85b22d57a1ddcbe32f52)をアップしていますので、そちらを参照して下さい。

# Environmentの設定

Watson StudioのJupyter Notebook環境でアニメーション表示をするためには、いくつかの不足モジュールの追加導入が必要です。
セルから ``!conda xxx``や``!pip xxx``を実行すればいいのですが、Notebookがきたなくなるし、いちいち実行するのが面倒なので、アニメーション表示用Environmentを作成することにします。

プロジェクト管理の画面から「**Environments**」タブをクリックして、「**New environment definition**」をクリックします。

![スクリーンショット 2018-07-28 17.15.49.png](https://qiita-image-store.s3.amazonaws.com/0/206130/4a33def2-4d77-668a-8aea-d0be95e34b65.png)

下の画面が出てきたら、名前を「animation-env」などとし、後はデフォルトで「**Create**」

![スクリーンショット 2018-07-28 17.20.25.png](https://qiita-image-store.s3.amazonaws.com/0/206130/11064456-4fe6-ec6e-8fd7-e513961677fb.png)

次の画面になったら、画面中程の**Customization**の欄にある「**Create**」リンクをクリック。

![スクリーンショット 2018-07-28 17.22.30.png](https://qiita-image-store.s3.amazonaws.com/0/206130/3898d034-ec99-d184-f793-b2092a47429c.png)

下の図のように「Customization」の欄ができるので、内容を下記のテキストに置き換えて「**Apply**」

![スクリーンショット 2018-07-28 17.25.04.png](https://qiita-image-store.s3.amazonaws.com/0/206130/d7a5c09d-caaa-ffcd-6876-a65ea53e5dd3.png)

```
# Please add conda channels here
channels:
- conda-forge

# Please add conda packages here
dependencies:
- ffmpeg=4.0.2

# Please add pip packages here
# To add pip packages, please comment out the next line
- pip:
  - numpy==1.14.2
  - matplotlib==2.2.2
  - gym==0.10.5
  - JSAnimation==0.1
  - pyglet==1.2.4
```

# Notebookファイルの新規作成
保存が正常に終わったら、プロジェクト管理のメイン画面に戻ります。
「Add to project」から「Notebook」を選択し、新規ノートブック作成画面を表示します。
Notebook作成時、必ず「**Select runtime**」の欄で先ほど作ったEnvironmentである「**animation-env**」を選択するようにして下さい。
これは、既存Notebookファイルを読み込んでアニメーション表示する場合も同じです。

![スクリーンショット 2018-07-28 17.29.15.png](https://qiita-image-store.s3.amazonaws.com/0/206130/f7eb9ca8-167a-3d5a-be9c-c40f836b312d.png)

以下では、いくつかのサンプルコードを添付します。

# サンプルコード1
正弦曲線による波動のアニメーションです。

初期設定

```py3
# 必要ライブラリのロード
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from IPython.display import HTML

# 初期画面の描画
fig, ax = plt.subplots()

# x軸、y軸の範囲
ax.set_xlim(( 0, 2))
ax.set_ylim((-2, 2))

# グラフの線は枠だけ用意しておきます。
line, = ax.plot([], [], lw=2)

```

アニメーション表示

```py3
# 初期化関数
def init():
    line.set_data([], [])
    return (line,)

def animate(i):
    x = np.linspace(0, 2, 1000)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    line.set_data(x, y)
    return (line,)

# アニメーションの定義
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=100, interval=20, blit=True, repeat=True)

# アニメーションの描画
HTML(anim.to_html5_video())
```

うまくいくと、こんな画面が表示されます。

![スクリーンショット 2018-07-28 17.39.31.png](https://qiita-image-store.s3.amazonaws.com/0/206130/da68255d-a956-27d7-a5d7-7cc7f0361d05.png)

# サンプルコード2
点が動いて円を描く様子です。

初期設定

```py3
# 必要なライブラリのロード
%matplotlib inline
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
from IPython.display import HTML

# 初期画面の表示
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(111)
ax.set_ylim(-1.5, 1.5)
ax.set_xlim(-1.5, 1.5)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid()
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
```

アニメーション表示

```py3
# 円弧曲線と点の初期定義
curve, = ax.plot([], [], 'b-', lw=2)
point, = ax.plot([], [], 'bo', ms=4)
xx, yy = [], []

# 描画用パラメータ生成関数
def gen():
    for x in np.linspace(0,2,100):
        theta = x * np.pi 
        yield np.cos(theta), np.sin(theta), x

# 描画用関数
def func(data):
    # パラメータの受け取り
    x, y, Rt = data
    # テキスト表示
    time_text.set_text('theta = %.2f pi' % Rt)
    # 円弧用ベクトルの生成
    xx.append(x)
    yy.append(y)
    # 円弧と点の描画
    curve.set_data(xx, yy)
    point.set_data(x, y)
    
# アニメーションの表示
anim = animation.FuncAnimation(fig,
        func, gen, blit=False, interval=100, repeat=False)
HTML(anim.to_html5_video())    
```

うまくいくとこんな画面が表示されます。

![スクリーンショット 2018-07-28 17.45.20.png](https://qiita-image-store.s3.amazonaws.com/0/206130/67c07ebb-f0bf-5f6f-9ce9-aa67a96129bf.png)


# サンプルコード3
サイクロイド曲線です。

初期画面表示

```py3
# 必要ライブラリのロード
%matplotlib inline
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
from IPython.display import HTML

# 初期グラフの描画
fig = plt.figure(figsize=(15,4))
ax = fig.add_subplot(111)
ax.set_ylim(-0.5, 2.5)
ax.set_xlim(0, 15)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid()
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
```

アニメーションの表示

```py3
# 曲線と点の変数宣言
cycloid, = ax.plot([], [], 'b-', lw=2)
point, = ax.plot([], [], 'bo', ms=4)
xx, yy = [], []

# パラメータ生成関数
def gen():
    for theta in np.linspace(0,6*np.pi,100):
        yield theta-np.sin(theta), 1-np.cos(theta), theta
        
# アニメーション表示用関数
def func(data):
    # パラメータの受け取り
    x, y, Rt = data
    # テキスト表示
    time_text.set_text('theta = %.2f pi' % (Rt/np.pi))
    # 曲線のデータ生成
    xx.append(x)
    yy.append(y)
    # グラフ表示
    cycloid.set_data(xx, yy)
    point.set_data(x, y)

# アニメーション表示
anim = animation.FuncAnimation(fig,
        func, gen, blit=False, interval=100, repeat=False)
HTML(anim.to_html5_video())    
```

うまくいくと、以下のようにサイクロイド曲線のアニメーションが表示されます。

![スクリーンショット 2018-07-28 17.49.46.png](https://qiita-image-store.s3.amazonaws.com/0/206130/6b5b8885-32a4-abab-461e-6feade118fd8.png)