はじめに
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
コメント