はじめに
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ファイル)
コメント