[matplotlib animation] 4.球の拡大・収縮アニメーション

matplotlib Animation

はじめに

python matplotlibで拡大・収縮する球のanimationについて解説する。

コード

解説

下記記事では、球が回転するアニメーションを作成した。今回は、球が拡大・収縮するアニメーションを作成する。

[matplotlib animation] 3.球のz軸回転アニメーション
matplotlibのmplot3dで作成した球のsurface plotをZ軸に対して回転させたアニメーションについて解説します。

3Dグラフにする設定

fig = plt.figure(figsize=(7,7))
ax = fig.gca(projection='3d')

プロットするデータの生成

u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
r = np.hstack((np.linspace(0, 10, 50),np.linspace(10, 0, 50)))
x = np.outer(np.cos(u), np.sin(v))
y = np.outer(np.sin(u), np.sin(v))
z = np.outer(np.ones(np.size(u)), np.cos(v))

u, v は極座標でいう、θとφ。極座標で球は以下の通りとなる。

$$x=rcos\theta sin\phi, y=rsin\theta sin\phi, z=rcos\phi$$

プロットできるようにするために、meshgrid状のデータを作成する。
np.outer()は外積で、2つのデータの要素の全てを掛け合わせることをする。[1]
np.size()は要素を返してくれるのでnp.size(u)は100で、
np.ones(100)となるので1が100個のデータができる。

これで、(0,0,0)に半径1の球ができる。
rは球の径の大きさに関する設定。

軸の範囲、ラベルの設定

ax.set_xlim(10.1,10.1)
ax.set_ylim(-10.1,10.1)
ax.set_zlim(-10.1,10.1)
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")

半径10まで大きくなるので、10.1まで表示するように設定する。

3D surfaceグラフの作成

plot= [ax.plot_surface(x, y, z)]

plotは[]で囲んでリストにしなければならない。

アニメーションで表示するグラフの設定

def update(num,x,y,z,r,plot):
    plot[0].remove()
    x_= r[num]*x
    y_ = r[num]*y
    z_ = r[num]*z
    plot[0] = ax.plot_surface(x_, y_, z_, cmap="plasma")

このanimationは、plot[0]を随時更新していくことでアニメーションとする。
そのため、最初に前のグラフをremove()で取り除く。
そして、rの各要素をx,y,zにかけて、プロットを順次作成する。

アニメーションの設定

ani = animation.FuncAnimation(fig, update, 100, fargs=(x,y,z,r,plot), interval=100)
HTML(ani.to_html5_video())

FuncAnimationでアニメーションの作成。
figにupdateのanimatonを描いて、frame数は100, intervalは100 msなので10 sの動画。fargsはupdateに渡す引数なので、x,y,z,rとplotを入れる[3]

HTML(ani.to_html5_video())でjupyter notebook上にアニメーションを表示できる。

アニメーションの保存

dpi=100
ani.save('expand_ball.mp4', writer="ffmpeg",dpi=dpi)

dpiで解像度を設定して、.saveにファイル名、writerとdpiをいれることで保存できる。

コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

参考

  1. NumPy で線形代数 – Python でデータサイエンス

コメント