如何将Matplotlib滑块与FuncAnimation结合实现实时参数更新?
问题解决:滑块控制FuncAnimation实时更新参数
核心需求
已实现基于FuncAnimation的量子波包动画,希望通过滑块修改势能参数V0,实时重新计算入射波、反射波、透射波数组(psi_i,psi_r,psi_t),并更新动画。
关键修改点
- 将
psi_i,psi_r,psi_t设为全局变量,让滑块更新函数可直接修改它们 - 关闭动画的帧缓存(
cache_frame_data=False),确保每次动画帧都使用最新计算的波函数 - 在滑块更新函数中,根据滑块值反推原始V0,重新调用
psi_step计算新的波函数数组,同时更新势能曲线
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.widgets import Slider from matplotlib.animation import FuncAnimation from paquet_onde_v_17_03 import V0,k,Ak,Ek,evolution,psi_step # 全局变量存储波函数数组,方便滑块更新函数修改 psi_i, psi_r, psi_t = None, None, None #------------------------------------------------------------------------------ # 初始化图形和显示范围 fig, ax = plt.subplots(figsize=(15,8)) plt.subplots_adjust(bottom=0.25, left=0.05, right=0.95) ax.set(xlim=(-2, 2), ylim=(-17, 17)) line, = ax.plot([], []) line1,= ax.plot([], []) line2,= ax.plot([], []) line3,= ax.plot([], []) plt.grid(True) # k空间参数 k0 = 100 E0 = 1.5*k0**2 sigma_k = 5 delta_k = 1 # x空间参数 xmin = -2 xmax = 2 N = 1500 x = np.linspace(xmin,xmax,N) x1 = np.linspace(xmin,0,int(N/2)) x2 = np.linspace(0,xmax,int(N/2)) # 初始化全局波函数数组 psi_i, psi_r, psi_t = psi_step(k, x, V0) # 动画初始化函数 def init(): line.set_data([], []) line1.set_data([], []) line2.set_data([], []) line3.set_data([], []) return line,line1,line2,line3 # 动画帧更新函数 T = 2e-4 t0=0.029 def animate(i): y1 = evolution(psi_i,Ak,Ek,i*T-t0) y2 = evolution(psi_r,Ak,Ek,i*T-t0) y3 = evolution(psi_t,Ak,Ek,i*T-t0) line1.set_data(x1,y1) line2.set_data(x1,y2) line3.set_data(x2,y3) return line,line1,line2,line3 # 关闭帧缓存,确保每次使用最新波函数 anim = FuncAnimation(fig, animate, init_func=init, frames=600, interval=10, cache_frame_data=False) # 势能曲线相关 scale=5.5e-4 def V(x,V0): return scale*V0*(np.sign(x)+1) plotstep, = plt.plot(x, V(x,V0), '--', color='k') # 滑块创建 ax_newstep = fig.add_axes([0.1, 0.14, 0.65, 0.03]) s_newstep = Slider(ax_newstep, 'V0', 0.0, 8.3, valinit=scale*V0) # 滑块更新函数 def update_plot_step(val): global psi_i, psi_r, psi_t # 从滑块值反推原始V0参数 new_V0 = val / scale # 重新计算波函数数组 psi_i, psi_r, psi_t = psi_step(k, x, new_V0) # 更新势能曲线 plotstep.set_ydata(val*(np.sign(x) + 1)) # 触发图形重绘 fig.canvas.draw_idle() s_newstep.on_changed(update_plot_step) plt.show()
说明
- 全局变量
psi_i,psi_r,psi_t让滑块修改函数可直接更新波函数数据 cache_frame_data=False禁用动画帧缓存,避免使用旧的波函数数据- 滑块值是缩放后的势能高度,需通过
new_V0 = val / scale转换回原始V0参数,再传入psi_step计算新波函数 - 滑块调整后,自动重新计算波函数并更新势能曲线,动画会使用新数据生成下一帧
内容的提问来源于stack exchange,提问作者Malo
相关产品推荐
相关产品推荐

