如何将matplotlib绘制的3D图导出为360度环绕旋转的视频
matplotlib 3D旋转视频导出问题解决方案
核心问题原因
- 变量作用域错误:
fig和ax定义在init()函数内部,属于局部变量,外部的动画逻辑无法访问正确的画布、坐标轴对象,导致每帧独立生成新的绘图窗口,无法拼接为视频 - 3D绘图对
blit=True适配性差,开启后容易出现渲染异常 - 未安装ffmpeg编码器会导致视频导出失败,matplotlib需要依赖该工具生成mp4文件
修正后的可运行代码
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import animation # 提前定义全局的画布和坐标轴对象,保证所有函数可以访问 fig = plt.figure() ax = fig.add_subplot(111, projection="3d") points = np.array ([[[472.983284, 114.5,-1792.], [720.65216064, 1535.5, -1792.], [1500.20385742, 1535.5, -1008.], [1252.39562988, 114.5, -1008.]]]) def init(): # 初始化仅做绘图逻辑,不用重复创建画布 ax.cla() for i in points: x = np.array([[i[0,0], i[-1,0]], [i[1,0], i[2,0]]]) y = np.array([[i[0,1], i[-1,1]], [i[1,1], i[2,1]]]) z = np.array([[i[0,2], i[-1,2]], [i[1,2], i[2,2]]]) ax.plot_surface(x, y, z) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') return def animate(i): # 直接修改全局ax的视角,azim从0到360旋转 ax.view_init(elev=10., azim=i) return # 生成动画,关闭blit参数 anim = animation.FuncAnimation(fig, animate, init_func=init, frames=360, interval=20, blit=False) # 保存为视频,确保本地已经安装ffmpeg anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264']) # 运行结束后自动关闭画布 plt.close()
额外注意事项
- 如果运行时提示找不到ffmpeg,Windows系统可以下载ffmpeg编译好的二进制文件,添加到系统环境变量即可;Linux系统可以通过包管理器直接安装,Mac系统可以通过brew安装
- 不需要弹出交互窗口的话可以删除
%matplotlib qt5这行代码,脚本模式下默认使用非交互后端更适合导出视频 - 如果需要调整旋转速度,可以修改
fps参数或者frames参数,总时长=帧数/帧率,360帧、30fps的配置总时长为12秒,刚好旋转一周
内容的提问来源于stack exchange,提问作者Link_tester
相关产品推荐
相关产品推荐

