如何保存含播放时视角变更的Matplotlib 3D动画并实现边看边录
解决方案
核心是手动接管帧录制逻辑,不用FuncAnimation自带的save()方法,这样可以捕获交互调整视角后的实时画布内容:
修改后的完整代码
import numpy as np import matplotlib import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib import animation from mpl_toolkits.mplot3d import Axes3D # 请确保使用交互后端,否则无法拖动调整视角 matplotlib.use('TkAgg') matplotlib.rcParams['animation.ffmpeg_path'] = r'C:\Users\harry\.ipython\ffmpeg-2021-07-25-git-a2a7547b2f-essentials_build\ffmpeg-2021-07-25-git-a2a7547b2f-essentials_build\bin\ffmpeg.exe' # -------------------------- # 以下为示例初始化逻辑,可直接替换为你自己的计算、绘图初始化代码 nt = 200 # 总帧数,和你原有参数保持一致 fig = plt.figure(figsize=(10,7)) ax = fig.add_subplot(111, projection='3d') # 初始化散点对象 scat = ax.scatter([], [], [], s=20) # 坐标轴范围替换为你自己的数值 ax.set_xlim(-1, 1) ax.set_ylim(-1, 1) ax.set_zlim(-1, 1) # 你的帧更新函数,替换为自己的逻辑即可 def update(frame): # 示例:生成随机散点,替换为你自己的坐标计算逻辑 x = np.random.randn(50) y = np.random.randn(50) z = np.random.randn(50) scat._offsets3d = (x, y, z) # 核心新增:每次更新完画面就抓取当前帧写入视频,此时画面已包含你调整后的视角 if save: writervideo.grab_frame() return scat, # -------------------------- save = True # 改为True即可开启边播放边录制 # 提前初始化并打开视频写入器 if save: f = r"D:\harry\Documents\Python_Scripts\3D\videos\scatter-TEST.mov" writervideo = animation.FFMpegWriter(fps=30) writervideo.setup(fig, f, dpi=100) # 初始化动画,interval建议设为33左右(对应30fps),太快不方便调整视角 anim = FuncAnimation(fig, update, frames=nt, repeat=False, interval=33 ) # 动画播放结束后自动关闭写入器,避免视频文件损坏 def close_writer(event): if save: writervideo.finish() fig.canvas.mpl_connect('close_event', close_writer) plt.show()
关键改动说明
- 更换为交互后端(如
TkAgg),确保可以在播放窗口中拖动调整3D视角 - 不使用
anim.save(),改为手动管理FFMpegWriter的生命周期 - 在
update函数末尾添加帧抓取逻辑,每次渲染完画面就抓取当前帧,此时的画面包含你手动调整的视角参数 - 添加窗口关闭回调,动画结束后自动结束视频写入,避免文件损坏
注意事项
- 播放过程中可以随时用鼠标拖动3D视图调整视角,调整后的画面会自动同步到录制的视频中
- 如果觉得动画播放太快来不及调整视角,可以调大
interval参数,同时对应调低fps参数(比如interval设为50,fps设为20),保证视频播放速度和实际模拟速度一致
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

