You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python生成多图叠加动画?附报错与代码求助

问题解决:Matplotlib叠加曲线动画报错

错误原因分析

  1. 动画提前销毁:代码末尾的plt.close()会直接关闭绘图窗口,导致FuncAnimation创建的动画对象ani在plt.show()执行前就被销毁,触发警告。
  2. 绘图参数错误:animate函数中plt.plot(r[n], Sevol[n])的参数有误,r[n]是单个数值,应该用完整的r数组绘制对应时间步的Sevol[n]曲线。
  3. 坐标轴标签重复设置:连续两次调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:15:51