如何用Python生成多图叠加动画?附报错与代码求助
问题解决:Matplotlib叠加曲线动画报错
错误原因分析
- 动画提前销毁:代码末尾的
plt.close()会直接关闭绘图窗口,导致FuncAnimation创建的动画对象ani在plt.show()执行前就被销毁,触发警告。 - 绘图参数错误:
animate函数中plt.plot(r[n], Sevol[n])的参数有误,r[n]是单个数值,应该用完整的r数组绘制对应时间步的Sevol[n]曲线。 - 坐标轴标签重复设置:连续两次调用
plt.xlabel,导致y轴缺失标签,需将第二个改为plt.ylabel('S')。
修正后的完整代码
import numpy as np import math import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation nr = 300 ri = 0 rf = 300 dr = (rf - ri) / (nr - 1) nt = 1000 dt = 0.1 r = np.linspace(ri, rf, num=nr) def rk3_step(t, h, y, f, *args): k1 = h * f(t , y , *args) k2 = h * f(t + h/2, y + 1/2 * k1 , *args) k3 = h * f(t + h , y - k1 + 2 * k2, *args) return y + 1/6*(k1 + 4*k2 + k3) def rhs_perturb(t, u): S = u.T[0] S_dot = u.T[1] F = u.T[2] F_dot = u.T[3] rhs = np.empty((nr, 4)) rhs[0] = np.array([S_dot[0], (S[2] - 2 * S[1] + S[0]) / (dr ** 2), # + F[0], F_dot[0], - S[0] + (F[2] - 2 * F[1] + F[0]) / (dr ** 2)]) rhs[-1] = np.array([S_dot[-1], (S[-1] - 2 * S[-2] + S[-3]) / (dr ** 2), # + F[-1], F_dot[-1], - S[-1] + (F[-1] - 2 * F[-2] + F[-3]) / (dr ** 2)]) for i in range(1, nr - 1): rhs[i] = np.array([S_dot[i], (S[i + 1] - 2 * S[i] + S[i - 1]) / (dr ** 2), # + F[i], F_dot[i], - S[i] + (F[i + 1] - 2 * F[i] + F[i - 1]) / (dr ** 2)]) return rhs sigma = 3 r0 = 100 F = np.empty(nr) F_dot = np.empty(nr) S = np.empty(nr) S_dot = np.empty(nr) for i in range(nr): F[i] = 0 F_dot[i] = 0 S_dot[i] = 0 S[i] = math.exp(-(r[i] - r0)**2 / sigma**2) uin = np.block([[S], [S_dot], [F], [F_dot]]).T u = np.copy(uin) uaux = np.copy(uin) nsave = 10 Sevol = np.empty((math.floor(nt/nsave),nr)) Sevol[0] = S Fevol = np.empty((math.floor(nt/nsave),nr)) Fevol[0] = F for n in range(nt): uaux = rk3_step(n * dt, dt, u, rhs_perturb) if np.any(np.isnan(uaux)): break u = uaux if (n + 1) % nsave == 0: Sevol[math.floor(n / nsave)] = u.T[0] Fevol[math.floor(n / nsave)] = u.T[2] fig = plt.figure() plt.xlabel('r') plt.ylabel('S') # 修正重复的xlabel为ylabel plt.grid() plt.xlim(ri, rf) # 保存已绘制的曲线,避免重复绘制 lines = [] def animate(i): numPlots = i // 10 # 仅绘制新增的曲线 while len(lines) < numPlots: n = len(lines) line, = plt.plot(r, Sevol[n], color='gold', markersize=3) lines.append(line) return lines ani = FuncAnimation(fig, animate, frames=100, interval=10, blit=False, repeat=False) # 移除plt.close(),保留窗口直到动画展示结束 plt.show()
关键修改说明
- 删除
plt.close():确保动画对象在plt.show()执行前不会被销毁,解决警告问题。 - 修正绘图参数:将
plt.plot(r[n], Sevol[n])改为plt.plot(r, Sevol[n]),绘制完整的空间分布曲线。 - 优化动画逻辑:用列表
lines存储已绘制的曲线,每次帧只添加新曲线,避免重复绘制提升性能。 - 修复坐标轴标签:将重复的xlabel改为ylabel,明确坐标轴含义。
内容的提问来源于stack exchange,提问作者User8563
相关产品推荐
相关产品推荐

