📘

matplotlibで複数の物体の軌跡を3Dアニメーション

2023/01/16に公開

物体検出で得た座標をアニメーションした。

データの準備

物体id, (x, y, z)の各座標のデータフレームを用意
(randam生成でもOK)

画像でplot

各idごとにx, y, zの座標をプロットし、最後にshow()でグラフを表示することで、各idごとの軌跡を3Dプロットする。

import matplotlib.pyplot as plt

for id in data["id"].unique():
    x = data[data["id"] == id]["x"]
    y = data[data["id"] == id]["y"]
    z = data[data["id"] == id]["z"]
    plt.plot(x, y, z)
plt.show()

アニメーションでplot

軌跡を可視化するには、Pythonの3Dプロットライブラリの1つであるmplot3dを使用する。以下で、各idごとにx, y, zの座標をプロットし、軌跡を3Dプロットする。

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D

def update_lines(num, dataLines, lines):
    for line, data in zip(lines, dataLines):
        line.set_data(data[0:2, :num])
        line.set_3d_properties(data[2, :num])
    return lines

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

data = []
for id in df["id"].unique():
    x = df[df["id"] == id]["x"]
    y = df[df["id"] == id]["y"]
    z = df[df["id"] == id]["z"]
    data.append(np.array([x, y, z]))

lines = [ax.plot(dat[0, 0:1], dat[1, 0:1], dat[2, 0:1])[0] for dat in data]
ax.set_xlim3d([df["x"].min(), df["x"].max()])
ax.set_ylim3d([df["y"].min(), df["y"].max()])
ax.set_zlim3d([df["z"].min(), df["z"].max()])

ani = animation.FuncAnimation(fig, update_lines, len(df), fargs=(data, lines),
                              interval=50, blit=False)
plt.show()

output

Discussion