matplotlib 3D散点动画

matplotlib 3D scatter animation

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(100)
y = np.arange(100)
for t in range(100):
    z = np.ones(100)*t
fig = plt.figure(dpi=1200)
ax = fig.add_subplot(projection='3d')
ax.scatter(x,y,z)

我想根据t绘制动画情节。例如,当 t = 0 时首先绘制 (x[0], y[0], z)。然后当 t = 1 时绘制 (x[1], y[1],z),等等。但是,一旦新点显示,先前的点就会消失。请问我怎样才能做到这一点?谢谢你。 另外,如果我将 ax.scatter 更改为 ax.plot_surface,我将如何实现相同的结果?谢谢。

为了播放动画,我重新构建了您的代码。
首先,您需要定义一个函数 update ,您想要从一帧更改到下一帧的内容将被更新。在我们的例子中,在 update 函数中,我根据 t 参数更新 xyz 坐标。然后我清除之前的绘图并绘制一个具有更新坐标的新绘图。最后设置axis limits方便,以保持动画帧固定。

def update(t):
    ax.cla()

    x = np.cos(t/10)
    y = np.sin(t/10)
    z = 5

    ax.scatter(x, y, z, s = 100, marker = 'o')

    ax.set_xlim(-2, 2)
    ax.set_ylim(-2, 2)
    ax.set_zlim(-1, 10)

然后你创建一个图形和一个FuncAnimation实例,你将播放动画的图形,update函数和其他重要参数传递给它,如帧数,它们之间的间隔等等。有关详细信息,请参阅 documentation

fig = plt.figure(dpi=100)
ax = fig.add_subplot(projection='3d')

ani = FuncAnimation(fig = fig, func = update, frames = 100, interval = 100)

plt.show()

完整代码

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation


def update(t):
    ax.cla()

    x = np.cos(t/10)
    y = np.sin(t/10)
    z = 5

    ax.scatter(x, y, z, s = 100, marker = 'o')

    ax.set_xlim(-2, 2)
    ax.set_ylim(-2, 2)
    ax.set_zlim(-1, 10)


fig = plt.figure(dpi=100)
ax = fig.add_subplot(projection='3d')

ani = FuncAnimation(fig = fig, func = update, frames = 100, interval = 100)

plt.show()


如果你还想跟踪粒子轨迹,你可以添加XYZ列表来保存粒子坐标:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation


X = []
Y = []
Z = []


def update(t):
    ax.cla()

    x = np.cos(t/10)
    y = np.sin(t/10)
    z = t/10

    X.append(x)
    Y.append(y)
    Z.append(z)

    ax.scatter(x, y, z, s = 100, marker = 'o')
    ax.plot(X, Y, Z)

    ax.set_xlim(-2, 2)
    ax.set_ylim(-2, 2)
    ax.set_zlim(-1, 10)


fig = plt.figure(dpi=100)
ax = fig.add_subplot(projection='3d')

ani = FuncAnimation(fig = fig, func = update, frames = 100, interval = 100, repeat = False)

plt.show()