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

matplotlib Animation

はじめに

本記事は、Pythonのmatplotlibライブラリを使用して、3Dの球体が拡大・収縮するアニメーションを作成する方法について解説しています。球体の半径を時間の関数として変化させることで、拡大と収縮のエフェクトを実現する手法を紹介しています。また、matplotlibのAnimation機能を活用して、滑らかなアニメーション表示を行う方法も説明しています。

コード

解説

前回の記事では球が回転するアニメーションを作成しました。本記事では、球が拡大・収縮するアニメーションの作成方法を紹介します。

[matplotlib animation] 3.球のz軸回転アニメーション
matplotlibのmplot3dを使用して作成した3D球体モデルをZ軸周りに回転させるアニメーションの作成方法を解説しています。Pythonによる3Dアニメーション実装の基本から応用まで、コード例を交えて詳しく説明しています。

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")

このアニメーションは、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メソッドによるanimationを描画し、フレーム数は100、intervalは100msに設定することで10秒の動画になります。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ファイル)

まとめ

matplotlibを使った3D球体のアニメーション作成方法を学びました。特に半径を周期的に変化させることで、拡大・収縮するビジュアル効果を実現する手法を紹介しました。このテクニックは科学的なシミュレーションや教育目的のビジュアライゼーションに応用できます。

参考

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

コメント