はじめに
この記事は、matplotlib を使用して3D空間内のラインプロットをアニメーション化する方法について解説しています。3次元空間でのデータの時間変化を視覚的に表現するためのコードとその実装方法が示されています。
コード
解説
図の初期設定
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の動作を設定します。3D空間では、set_data(x,y,z)だけでは動作しないため、x,yをset_dataでセットし、z軸はset_3d_propertiesで別途設定する必要があります。
線グラフは始点から順にプロットしたいので: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グラフは空のデータセットで作成できないため、各データ配列の最初の要素を使用して初期プロットを生成します。
アニメーションの作成
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は100ミリ秒間隔なので、合計で100ミリ秒×300コマ=30秒の動画になります。fargsでupdate_lines関数の引数を指定し、init_funcで初期設定を行い、blitパラメータで描画を高速化します。repeat=Trueを設定することで、アニメーションは繰り返し再生されます。
HTMLに出力
HTML(line_ani.to_html5_video())
まとめ
matplotlibのAnimation機能と3D描画機能を組み合わせることで、時間とともに変化する3次元データを動的に可視化できます。これは科学的データの分析やシミュレーション結果の表示に非常に有用なテクニックです。
参考

コメント