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

matplotlib制作核素衰变动画首帧即显示完整曲线问题求助

代码核心问题

  • 初始化line1、line2两条曲线时,你直接传入了全量的N_I、N_Xe数据作为y值,即使后续修改x轴参数,y轴始终是完整的所有时间步结果,所以第一帧就会显示整条曲线。
  • animate函数逻辑错误:你没有随时间步截断y轴数据,反而把固定长度的x数据拉伸到0到j的区间,完全不符合逐步展示的需求。
  • 冗余计算问题:用循环迭代调用odeint求解完全没有必要,odeint本身支持传入完整时间序列直接输出所有时间步的结果,循环写法不仅运行效率低,还容易引入计算误差。
  • 原始绘图未指定x轴参数,默认x轴是数据点索引,不是实际的时间值,和你设置的x轴范围逻辑不符。

优化后的修正代码

# I135 Xe135 decay.
"""
    EQUATIONS:
    dIdt  = (-Lambda_I * N_I)
    dXedt = ((-Lambda_Xe * N_Xe) + (Lambda_I * N_I))
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from scipy.integrate import odeint

def model(z,t):
    """
     INITIAL CONDITIONS:
     I(0)  = 1e8 atoms
     Xe(0) = 0 atom

     PARAMETERS:
     Lambda_I
     Lambda_Xe
    """
    Lambda_I   = (np.log(2) / 6.57)
    Lambda_Xe  = (np.log(2) / 9.2)
    N_I  = z[0]
    N_Xe = z[1]
    dIdt  = (-Lambda_I * N_I)
    dXedt = ((-Lambda_Xe * N_Xe) + (Lambda_I * N_I))
    return [dIdt,dXedt]

z0 = [1e8, 0.0] # initial conditions for N_Xe and N_I
n  = 10000
max_time = 100
t  = np.linspace(0,max_time,n)

# 一次调用odeint得到全量结果,无需循环迭代
z = odeint(model, z0, t)
N_I  = z[:, 0]
N_Xe = z[:, 1]

# 绘图初始化
fig, ax = plt.subplots(figsize=(8,8))
ax.set_ylim(0, 1e8)
ax.set_xlim(0, max_time)
# 初始化线条时传入空数据,后续动画逐步填充
line1, = ax.plot([], [], 'b-',  linewidth=2, label='I-135')
line2, = ax.plot([], [], 'g-.', linewidth=2, label='Xe-135')
plt.rcParams['font.size'] = '14'
plt.minorticks_on()
plt.tick_params(axis="both", which="major", length=12, labelsize=12, width=1, color="black")
plt.tick_params(axis="both", which="minor", length=6, labelsize=10, width=0.8, color="black")
plt.title('I-135 Xe-135 Decay Sim.', fontsize=18)
plt.xlabel('Time (h)', fontsize=16)
plt.ylabel('N', fontsize=16)
plt.legend(prop={'size': 12})
plt.grid(color = 'black', linestyle = '--', linewidth = 0.6)

# 计算每帧对应的数据点数
step_per_frame = n // max_time
def animate(j):
    # 只取到当前时间步对应的数据做展示
    current_idx = j * step_per_frame
    line1.set_xdata(t[:current_idx])
    line1.set_ydata(N_I[:current_idx])
    line2.set_xdata(t[:current_idx])
    line2.set_ydata(N_Xe[:current_idx])
    return [line1, line2]

ani = animation.FuncAnimation(fig, animate, frames=max_time, blit=True, interval=20, save_count=max_time)
plt.show()

# 保存路径请根据本地目录修改
f = r"C://Users/USER_NAME/Desktop/animation.gif" 
writergif = animation.PillowWriter(fps=30) 
ani.save(f, writer=writergif)

额外优化建议

  • 可以在动画中添加当前时间的文本标注,更直观展示时间进度
  • 如果觉得动画太快来不及观察,可适当调大FuncAnimation的interval参数值(单位为毫秒)
  • 若需要更高清的GIF,可调整PillowWriter的dpi参数

内容的提问来源于stack exchange,提问作者Said

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 20:54:03