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

ipywidgets中FloatSlider控件游标无法移动问题求助

问题原因

滑块卡死的核心原因是绘图函数内的while循环逻辑存在漏洞,特定参数下会触发死循环:

  1. 代入参数可计算出油滴的终端速度约为6e-5 m/s,而你设置的v_0滑块最大值为10e-5,覆盖了初始速度超过终端速度的场景
  2. 现有循环判断条件v[-1] < (1-1e-4)*m*g/b or n_i < 100仅适配初始速度小于终端速度的场景:当初始速度大于终端速度时,油滴速度会从高值逐渐下降到终端速度,v[-1] < 阈值的条件永远成立,or逻辑会让循环持续执行,直接卡死交互进程。

修复方案

调整while循环的判断逻辑,兼容速度从上下两个方向趋近终端速度的场景,同时增加最大迭代次数上限避免极端情况卡死;建议将固定参数移到函数外预先计算,减少重复计算提升交互流畅度。

修复后完整代码

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import ipywidgets as widgets
import matplotlib.ticker as mtick

# 预先计算固定常量,避免每次调用函数重复计算
D = 1.5e-6 # 油滴直径 [m]
rho = 840 # 液体密度 [kg/m^3]
g = 9.8 # 重力加速度 [m/s^2]
V = np.pi/6*D**3 # 油滴体积 [m^3]
m = rho*V # 颗粒质量 [kg]
beta = 1.6e-4 # 空气动力粘度 [kg/ms]
b = beta*D # 线性摩擦系数 [kg/s]
v_terminal = m*g/b # 终端速度
error_thres = 1e-4 # 稳态误差阈值
max_iter = 10000 # 最大迭代次数兜底,彻底避免死循环

def plot_2_2(v_0=0,dt=7e-7):
    t_0 = 0 # 初始时间 [s]
    n_i = 0 # 迭代次数计数
    
    fig = plt.figure(constrained_layout=True, figsize=[14,8])
    spec = gridspec.GridSpec(ncols=1,nrows=2,figure=fig)
    ax1 = fig.add_subplot(spec[0,0])
    ax2 = fig.add_subplot(spec[1,0])

    t = [t_0]
    v = [v_0]

    # 修复后的循环条件:相对误差未达标 且 未超过最大迭代次数时继续执行
    while abs(v[-1] - v_terminal)/v_terminal > error_thres and n_i < max_iter:
        t.append(t[-1]+dt)
        v.append(v[-1]+(m*g-b*v[-1])*(dt)/m)
        n_i += 1
    
    t = np.array(t)
    v = np.array(v)
    v_analytic = v_0*np.exp(-b/m*t) + v_terminal*(1-np.exp(-b/m*t)) # 解析解

    l11, = ax1.plot(t,v,'r--') # 数值解
    l12, = ax1.plot(t, v_analytic,'kx') 
    l2, = ax2.plot(t,100*abs(v - v_analytic)/v_analytic,'c--') # 相对误差

    ax1.set_xlabel('时间 [s]')    
    ax1.set_ylabel('油滴速度 [m/s]')
    ax1.set_ylim(bottom=-0.5e-4,top=1.5e-4)
    ax1.ticklabel_format(axis="y", style="sci", scilimits=(0,0))
    ax1.set_title("油滴速度演变")
    ax1.grid(linestyle='-.')

    ax2.yaxis.set_major_formatter(mtick.PercentFormatter())
    ax2.set_xlabel('时间 [s]')    
    ax2.set_ylabel('相对误差')
    ax2.set_title("数值解 vs 解析解")
    ax2.grid(linestyle='-.')

    plt.show(fig)
    
widgets.interact(plot_2_2, 
                 v_0=widgets.FloatSlider(min=0,max=10e-5,step=1e-5,readout_format='.1e'), 
                 dt=widgets.FloatSlider(min=5e-7,max=10e-7,step=1e-7,readout_format='.1e'))

额外优化建议

运行代码前先执行%matplotlib widget魔法命令,可大幅提升matplotlib交互场景的流畅度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 13:06:09