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

Jupyter Notebook中Pyplot滑块无法更新绘图曲线的问题排查

四阶Runge-Kutta(RK4)求解ODE系统的交互式滑块修复

我使用四阶Runge-Kutta(RK4)方法近似求解一阶常微分方程(ODE)系统,RK4实现生成的绘图形态正确,但该方法依赖常数c、d、h,我希望通过滑块交互调整这些常数以观察解的变化。目前滑块可拖动但绘图不更新,已为c滑块绑定Slider.on_changed事件,重新调用RK4并设置曲线数据,但无效果且无报错。参考Matplotlib官方滑块示例在环境中可正常运行,排除环境交互问题。

最终定位到两个核心问题:

  • 曲线实例化方式错误
  • RK4未正确传递滑块参数

初始代码

%matplotlib notebook

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
import math

y_inits = [95, 5, 0]
c = 1
d = 5
fStepSize = 0.01
iLower = 0
iUpper = 1

tDerivatives = [
    lambda t, y1, y2, y3: -c*y1*y2,
    lambda t, y1, y2, y3: (c*y1*y2) - (d*y2),
    lambda t, y1, y2, y3: d*y2
]
   
tColors = ["blue", "red", "yellow", "green", "black", "purple"]
    
def RK4(c, d, fStepSize):
    
    tY_est = [ [y_inits[i]] for i in range(len(tDerivatives)) ]
    tT = [iLower]
    
    iRange = iUpper - iLower
    n = math.ceil(iRange / fStepSize)    
    
    for i in range(n+1)[1:]:
        
        fT_last = tT[i-1]
        fT_new = fT_last + fStepSize
        
        tK = []
        
        for j in range(len(tDerivatives)):
            Derivative = tDerivatives[j]
            fK1 = fStepSize * Derivative(fT_last, *[tY_est[k][i-1] for k in range(len(tY_est))])
            tK.append(["y'"+str(j+1), fK1])
        for j in range(len(tDerivatives)):
            Derivative = tDerivatives[j]
            fK2 = fStepSize * Derivative(fT_last + (fStepSize/2), *[tY_est[k][i-1] + (tK[k][1]/2) for k in range(len(tY_est))])
            tK[j].append(fK2)
        for j in range(len(tDerivatives)):
            Derivative = tDerivatives[j]
            fK3 = fStepSize * Derivative(fT_last + (fStepSize/2), *[tY_est[k][i-1] + (tK[k][2]/2) for k in range(len(tY_est))])
            tK[j].append(fK3)
        for j in range(len(tDerivatives)):
            Derivative = tDerivatives[j]
            fK4 = fStepSize * Derivative(fT_new, *[tY_est[k][i-1] + tK[k][3] for k in range(len(tY_est))])
            tK[j].append(fK4)    
        for j in range(len(tY_est)):
            fY_est_new = tY_est[j][i-1] + (( tK[j][1] + (2*tK[j][2]) + (2*tK[j][3]) + tK[j][4] )/6)
            tY_est[j].append(fY_est_new)
            
        tT.append(fT_new)

    return tT, tY_est 

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)

tT_init, tY_est_init = RK4(c, d, fStepSize)
tPlots = [ ax.plot(tT_init, tY_est_init[i], marker=".", color=tColors[i]) for i in range(len(tDerivatives)) ]
plt.xlabel('t')
plt.ylabel('y(t)')
plt.title('h = '+str(fStepSize))

axfreq = fig.add_axes([0.25, 0.1, 0.65, 0.03])
c_slider = Slider(
    ax=axfreq,
    label='c',
    valmin=0.1,
    valmax=30,
    valinit=c,
)

def Update(val):
    tT, tY_est = RK4(c_slider.val, d, fStepSize)
    for i in range(len(tPlots)):
        tPlots[i].set_data(tT, tY_est[i])
    fig.canvas.draw()

c_slider.on_changed(Update)

修正后的完整代码

%matplotlib notebook

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
import math

y_inits = [95, 5, 0]
c_init = 1
d_init = 5
fStepSize = 0.01
iLower = 0
iUpper = 1

tDerivatives = [
    lambda c, d, t, y1, y2, y3: -c*y1*y2,
    lambda c, d, t, y1, y2, y3: (c*y1*y2) - (d*y2),
    lambda c, d, t, y1, y2, y3: d*y2
]
   
tColors = ["blue", "red", "yellow", "green", "black", "purple"]
    
def RK4(c, d, fStepSize):
    
    tY_est = [ [y_inits[i]] for i in range(len(tDerivatives)) ]
    tT = [iLower]
    
    iRange = iUpper - iLower
    n = math.ceil(iRange / fStepSize)    
    
    for i in range(n+1)[1:]:
        
        fT_last = tT[i-1]
        fT_new = fT_last + fStepSize
        
        tK = []
        
        for j in range(len(tDerivatives)):
            Derivative = tDerivatives[j]
            fK1 = fStepSize * Derivative(c, d, fT_last, *[tY_est[k][i-1] for k in range(len(tY_est))])
            tK.append(["y'"+str(j+1), fK1])
        for j in range(len(tDerivatives)):
            Derivative = tDerivatives[j]
            fK2 = fStepSize * Derivative(c, d, fT_last + (fStepSize/2), *[tY_est[k][i-1] + (tK[k][1]/2) for k in range(len(tY_est))])
            tK[j].append(fK2)
        for j in range(len(tDerivatives)):
            Derivative = tDerivatives[j]
            fK3 = fStepSize * Derivative(c, d, fT_last + (fStepSize/2), *[tY_est[k][i-1] + (tK[k][2]/2) for k in range(len(tY_est))])
            tK[j].append(fK3)
        for j in range(len(tDerivatives)):
            Derivative = tDerivatives[j]
            fK4 = fStepSize * Derivative(c, d, fT_new, *[tY_est[k][i-1] + tK[k][3] for k in range(len(tY_est))])
            tK[j].append(fK4)    
        for j in range(len(tY_est)):
            fY_est_new = tY_est[j][i-1] + (( tK[j][1] + (2*tK[j][2]) + (2*tK[j][3]) + tK[j][4] )/6)
            tY_est[j].append(fY_est_new)
            
        tT.append(fT_new)

    return tT, tY_est 

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)

plt.xlabel('t')
plt.ylabel('y(t)')
plt.title('h = '+str(fStepSize))

c_slider = Slider(
    ax=fig.add_axes([0.25, 0.1, 0.65, 0.03]),
    label='c',
    valmin=0.1,
    valmax=5,
    valinit=c_init,
)
d_slider = Slider(
    ax=fig.add_axes([0.25, 0.06, 0.65, 0.03]),
    label='d',
    valmin=0.1,
    valmax=10,
    valinit=d_init,
)
h_slider = Slider(
    ax=fig.add_axes([0.25, 0.02, 0.65, 0.03]),
    label='h',
    valmin=0.001,
    valmax=0.1,
    valinit=fStepSize,
)

tPlots = [ax.plot([], [], marker=".", color=tColors[i])[0] for i in range(len(tDerivatives))]


def Update(val):
    fStepSize = h_slider.val
    tT, tY_est = RK4(c_slider.val, d_slider.val, fStepSize)
    for i in range(len(tPlots)):
        tPlots[i].set_data(tT, tY_est[i])
    fig.canvas.draw_idle()
    ax.relim()
    ax.autoscale_view()


c_slider.on_changed(Update)
d_slider.on_changed(Update)
h_slider.on_changed(Update)

tT_init, tY_est_init = RK4(c_init, d_init, fStepSize)
for i in range(len(tPlots)):
    tPlots[i].set_data(tT_init, tY_est_init[i])
ax.relim()
ax.autoscale_view()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:55:19