[matplotlib animation] 2.3D lineplot アニメーション

matplotlib Animation

はじめに

3Dグラフでのラインプロットのアニメーションを作成する方法について説明する。

コード

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

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

解説

図の初期設定

def init():
    ax.set_xlim(-2.1,2.1)
    ax.set_ylim(-2.1,2.1)
    ax.set_zlim(-2.1,2.1)
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.set_zlabel("z")
    #ax.set_aspect('equal')

    return lines

set_xlimなどで軸範囲を設定し、set_xlabelなどで軸ラベルを設定する。

アニメーションの設定

def update_lines(num, data, lines,points):
for dat,line, point in zip(data,lines, points):
line.set_data(dat[0:2, :num+1])
line.set_3d_properties(dat[2, :num+1])
point.set_data(dat[0:2, num])
point.set_3d_properties(dat[2, num])

return lines

この部分でanimationの動作を決める。z軸がある場合、set_data(x,y,z)では動かないので、x,yをset_dataでセットして、z軸はset_3d_propertiesでセットする。
lineは始点からプロットしたいので、:num+1, 点は1こだけなので、num。

3Dグラフの作成

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

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

t = np.linspace(-12np.pi,12np.pi,300)
z = np.linspace(-2, 2, 300)
r = np.sqrt(4-z*2)
x1, y1, z1 = rnp.sin(t), r*np.cos(t), z#プロットするデータ
data = np.array([[x1,y1,z1]])#プロットするデータ

このx1,y1,z1は

$$x^2+y^2+z^2=2^2$$

を満たすので半径2の円を回りながらラインプロットしていく。

lines = [ax.plot(dat[0, 0:1], dat[1, 0:1], dat[2, 0:1], 'm')[0] for dat in data]
points = [ax.plot(dat[0, 0:1], dat[1, 0:1], dat[2, 0:1], 'ro')[0] for dat in data]

プロットする図の設定。3Dグラフは空データで作成できないので、各データの1個目のデータでプロット作成。

アニメーションの作成

line_ani = animation.FuncAnimation(fig, update_lines, 300, fargs=(data, lines,points),
interval=100, init_func=init, blit=True, repeat=True)

figでupdate_linesを実行する。frames=300なので300コマ、でinterval=100は100msなので100 ms*300で30 sの動画となる。fargsでupdate_linesの引数を指定する。init_funcで初期設定をして,blitで描写の高速化。repeat=Trueで繰り返し再生される。

HTMLに出力

HTML(line_ani.to_html5_video())

参考

Draw 3D line animation using Python Matplotlib.FuncAnimation
draw 3D line animation using python matplotlib.funcanimation

コメント