[matplotlib animation] 3.球のz軸回転アニメーション

matplotlib Animation

コード

でできるアニメーション。

解説

↓では、視点をかえるアニメーションを作成した。今回は、プロット自体を軸に対して回転する。

3Dグラフにする設定

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

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

u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)

x = 2 * np.outer(np.cos(u), np.sin(v)) +6
y = 2 * np.outer(np.sin(u), np.sin(v))
z = 2 * 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個のデータができる。

xで+6しているので(6,0,0)に半径2の球ができる。

軸の範囲、ラベルの設定

ax.set_xlim(-8.1,8.1)
ax.set_ylim(-8.1,8.1)
ax.set_zlim(-8.1,8.1)
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
ax.set_aspect('equal')

ax.set_aspect(‘equal’)でx,y,z軸のアスペクト比が揃う。

3D surfaceグラフの作成

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

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

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

def update(num,x,y,z,u,plot):
plot[0].remove()
x_= x * np.cos(u[num]) - y * np.sin(u[num])#uの再利用
y_ = x * np.sin(u[num]) + y * np.cos(u[num])
plot[0] = ax.plot_surface(x_, y_, z, cmap="magma")

このanimationは、plot[0]を随時更新していくことでアニメーションとする。
なので、最初に前のグラフをremove()で取り除く。
そして、回転する。回転角をγとすると、Z軸周りに角度γ回転したときの式は、

$$x’=xcos\gamma – ysin\gamma\\y’=xsin\gamma + ycos\gamma\\z=z$$

となる[2]。

アニメーションの設定

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

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

HTMLの.to_html5_video()でアニメーションの表示。

参考

  1. 外積を求めるnumpy.outer関数の使い方 – DeepAge
  2. A.052. 3次元回転と極座標表示|エスオーエル株式会社
  3. Generate animation of 3D surface plot using plot_surface and …

コメント