Matplotlib画三维散点动图(代码及踩坑记录)

从npy文件中读取数据(shape: (720, 17, 3)),并绘制成720帧,每帧有17个点。

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

# load data
data = np.load('e:/keypoints3d.npy')  # shape: (720,17,3)

# set view
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')

ax.set_xlim([-100, 100])  # -67 49
ax.set_ylim([50, 250])  # 73 208
ax.set_zlim([-100, 100])  # -26 27

# draw animation
point, = ax.plot([], [], [], '.')

def update_point(n, data, point):
    print(n)
    frame_data = data[n].T
    x = frame_data[0]
    y = frame_data[1]
    z = frame_data[2]
    point.set_data([x, y])
    point.set_3d_properties(z)
    return point


ani = animation.FuncAnimation(fig, update_point, 720, fargs=(data, point), interval=3)

plt.show()

踩坑:
Animation报错:TypeError: object of type ‘numpy.float64’ has no len()
解决方法:把Matplotlib降级成3.4.3版本,然后就可以运行了。
https://github.com/matplotlib/matplotlib/issues/22308

其他参考的一些能运行起来的代码:
1、在三维空间动态画随机四十条线(官网)

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

# Fixing random state for reproducibility
np.random.seed(19680801)


def random_walk(num_steps, max_step=0.05):
    """Return a 3D random walk as (num_steps, 3) array."""
    start_pos = np.random.random(3)
    steps = np.random.uniform(-max_step, max_step, size=(num_steps, 3))
    walk = start_pos + np.cumsum(steps, axis=0)
    return walk


def update_lines(num, walks, lines):
    for line, walk in zip(lines, walks):
        # NOTE: there is no .set_data() for 3 dim data...
        line.set_data(walk[:num, :2].T)
        line.set_3d_properties(walk[:num, 2])
    return lines


# Data: 40 random walks as (num_steps, 3) arrays
num_steps = 30
walks = [random_walk(num_steps) for index in range(40)]

# Attaching 3D axis to the figure
fig = plt.figure()
ax = fig.add_subplot(projection="3d")

# Create lines initially without data
lines = [ax.plot([], [], [])[0] for _ in walks]

# Setting the axes properties
ax.set(xlim3d=(0, 1), xlabel='X')
ax.set(ylim3d=(0, 1), ylabel='Y')
ax.set(zlim3d=(0, 1), zlabel='Z')

# Creating the Animation object
ani = animation.FuncAnimation(
    fig, update_lines, num_steps, fargs=(walks, lines), interval=100)

plt.show()

2、三维空间中每次增加一个点

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

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

# create the parametric curve
x = np.random.random(100)
y = np.random.random(100)
z = np.random.random(100)

# create the first plot
point, = ax.plot([], [], [], 'r.')
point2, =ax.plot([], [], [], '.')
# line, = ax.plot(x, y, z, label='parametric curve')
# ax.legend()
ax.set_xlim([0, 1])
ax.set_ylim([0, 1])
ax.set_zlim([0, 1])

# second option - move the point position at every frame
def update_point(n, x, y, z, point):
    point2.set_data([x[0:n], y[0:n]])
    point2.set_3d_properties(z[0:n])
    point.set_data([x[n], y[n]])
    point.set_3d_properties(z[n])
    #point.set_array([255,0,0])
    return point

ani=animation.FuncAnimation(fig, update_point, 99, fargs=(x, y, z, point))

plt.show()

你可能感兴趣的:(matplotlib,python,numpy)