Matplotlib动画无法生成动态GIF及通用图例设置求助
Matplotlib动画生成与通用图例设置解决方案
1. 生成可正常展示的动态动画
针对静态白图问题,按以下步骤修复:
补全未定义变量与匹配数据维度
代码中Nsave未定义,且示例数据中Fevol/Sevol等仅包含3帧数据,同时r的长度(10)与每帧数据长度(6)不匹配,会导致绘图失败。需:- 定义
Nsave(示例中设为1,可根据实际需求调整); - 将
N_plots设为len(Fevol),避免索引越界; - 截取
r的前6个元素,保证与每帧数据长度一致。
- 定义
安装动画保存依赖
生成GIF需要pillow库,执行命令安装:pip install pillow调整动画渲染与保存逻辑
- 在Jupyter环境中,先运行
%matplotlib notebook或%matplotlib widget启用交互式渲染; - 保存GIF时,使用
PillowWriter作为写入器,避免格式兼容问题; - 动画返回值需包含更新的图例对象,确保图例随帧同步更新。
- 在Jupyter环境中,先运行
2. 设置通用「Tempo(时间)」图例
不要给每个子图的曲线添加重复时间标签,而是创建全局图例固定在画布位置:
- 创建全局空图例
移除每个ax.plot()中的label参数,单独创建仅含时间文本的图例,通过bbox_to_anchor定位在画布右上角,实现所有子图共用。 - 在动画函数中更新图例文本
直接修改全局图例的文本内容,无需重复创建图例。
修改后的完整代码
import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation # 示例数据 r = [1.00000000e-05, 2.51645972e-04, 4.93291945e-04, 7.34937917e-04, 9.76583890e-04, 1.21822986e-03] # 截取前6个元素匹配数据长度 Fevol = [[ 5.11496045e-45, 8.15102513e-41, 6.13980179e-40,-4.30628127e-11, -3.89519864e-11, -3.45608037e-11],[ 2.03678046e-47, 3.24574332e-43, 2.44487293e-42,-1.57997251e-10, -1.49417738e-10, -1.40558032e-10], [-9.13815280e-46, -1.45622461e-41, -1.09690871e-40,-3.44502060e-10, -3.31446469e-10, -3.18110822e-10]] Sevol = [[ 4.01126611e-40, 6.39221577e-36, 4.81496956e-35, 4.78940796e-06, 4.78920837e-06, 4.78900809e-06], [-5.54576762e-41, -8.83754463e-37, -6.65692616e-36, 4.79261266e-06, 4.79241231e-06, 4.79221192e-06], [ 6.66114341e-41, 1.06149691e-36, 7.99578035e-36, 4.79582115e-06, 4.79562050e-06, 4.79541987e-06]] Hevol = [[ 5.01995518e-44, 3.17892153e-41, 1.22154055e-40, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [ 1.67719339e-44, 1.06209438e-41, 4.08123113e-41, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [-1.81140980e-45, -1.14708786e-42, -4.40782924e-42, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]] Hamiltevol = [[ 9.90241594e-08, -3.07539672e-31, -5.13492241e-31, 4.69149764e-14, 4.69308735e-14, -1.19340169e-05], [ 9.90241594e-08, -3.07539672e-31, -5.13492241e-31, 4.69149764e-14, 4.69308735e-14, -1.19340169e-05], [ 9.90241594e-08, -3.07539672e-31, -5.13492241e-31, 4.69149764e-14, 4.69308735e-14, -1.19340169e-05]] # 初始化参数 Nsave = 1 # 补全未定义变量 N_plots = len(Fevol) # 匹配实际帧数 ri = 0.00001 rf = 15 radius = 0.15 dt = 0.0001 NewtonG = 6.67408*10**(-8) LightC = 2.99792458*10**10 rho_dim = 2.7 * (10 ** (14)) fig, ((axF, axS), (axH, axHamilt)) = plt.subplots(2, 2, gridspec_kw={'hspace': 0.4, 'wspace': 0.3}) # 创建各子图曲线,不添加label graphF, = axF.plot([], []) graphS, = axS.plot([], []) graphH, = axH.plot([], []) graphHamilt, = axHamilt.plot([], []) # 创建通用时间图例,定位在画布右上角 L = fig.legend([graphF], ['Tempo: 0 s'], loc="upper right", bbox_to_anchor=(0.95, 0.95)) # 设置子图属性 axF.set_ylim(-1.5, 1.5) axF.set_xlim(ri, rf) axF.grid() axF.set_title('F X r') axS.set_ylim(-0.5, 0.5) axS.set_xlim(ri, rf) axS.grid() axS.set_title('S X r') axH.set_ylim(-0.3, 0.3) axH.set_xlim(ri, 1.1 * radius) axH.grid() axH.set_title('H x r') axHamilt.set_ylim(-0.5, 0.5) axHamilt.set_xlim(ri, rf) axHamilt.grid() axHamilt.set_title('Hamiltonian X r') # 设置曲线颜色(放在初始化,无需每帧重复设置) graphS.set_color("darkorange") graphH.set_color("forestgreen") graphHamilt.set_color("red") def animate(i): # 计算当前时间 time = round(dt + i * dt * Nsave * ((LightC / (NewtonG * rho_dim) ** (1/2)) / LightC), 4) lab = f'Tempo: {time} s' # 更新各曲线数据 graphF.set_data(r, Fevol[i]) graphS.set_data(r, Sevol[i]) graphH.set_data(r, Hevol[i]) graphHamilt.set_data(r, Hamiltevol[i]) # 更新图例文本 L.get_texts()[0].set_text(lab) # 返回所有需要更新的元素(包括图例) return graphF, graphS, graphH, graphHamilt, L # 创建动画 ani = FuncAnimation(fig, animate, frames=N_plots, interval=100, blit=True) # 保存为GIF(需安装pillow) ani.save('evolution_animation.gif', writer='pillow', dpi=100) # 在Jupyter中显示动画 plt.show()
内容的提问来源于stack exchange,提问作者Projetos Programação
相关产品推荐
相关产品推荐

