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

两段相似Python Bokeh代码一段滑块无响应,求故障原因

Bokeh滑块无响应问题排查与修复

问题描述

我有两段结构相似的Python代码,均使用Bokeh库制作交互式绘图。其中一段参考自网络的代码可正常运行;另一段实现了更复杂的函数绘图,虽能生成初始图像,但滑块调节无响应。除检查拼写错误外,暂无其他排查思路,请问该代码失效的原因是什么?

正常运行代码

import numpy as np

from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, CustomJS, Slider
from bokeh.plotting import figure, show

x = np.linspace(0, 10, 500)
y = np.sin(x)

source = ColumnDataSource(data=dict(x=x, y=y))

plot = figure(y_range=(-10, 10), width=400, height=400)

plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

amp = Slider(start=0.1, end=10, value=1, step=.1, title="Amplitude")
freq = Slider(start=0.1, end=10, value=1, step=.1, title="Frequency")
phase = Slider(start=-6.4, end=6.4, value=0, step=.1, title="Phase")
offset = Slider(start=-9, end=9, value=0, step=.1, title="Offset")

callback = CustomJS(args=dict(source=source, amp=amp, freq=freq, phase=phase, offset=offset),
                    code="""
    const A = amp.value
    const k = freq.value
    const phi = phase.value
    const B = offset.value

    const x = source.data.x
    const y = Array.from(x, (x) => B + A*Math.sin(k*x+phi))
    source.data = { x, y }
""")

amp.js_on_change('value', callback)
freq.js_on_change('value', callback)
phase.js_on_change('value', callback)
offset.js_on_change('value', callback)

show(row(plot, column(amp, freq, phase, offset)))

滑块无响应代码

import numpy as np

from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, CustomJS, Slider
from bokeh.plotting import figure, show

x = np.linspace(0, 10, 500)
y = np.sin(x)

source = ColumnDataSource(data=dict(x=x, y=y))

plot = figure(y_range=(-10, 10), width=400, height=400)

plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

amp1 = Slider(start=0, end=10, value=1, step=.1, title="Amplitude 1")
amp2 = Slider(start=0, end=10, value=0, step=.1, title="Amplitude 2")
freq1 = Slider(start=0, end=10, value=1, step=.1, title="Frequency 1")
freq2 = Slider(start=0, end=10, value=0, step=.1, title="Frequency 2")
phase1 = Slider(start=-6.4, end=6.4, value=0, step=.1, title="Phase 1")
phase2 = Slider(start=-6.4, end=6.4, value=0, step=.1, title="Phase 2")
offset1 = Slider(start=-9, end=9, value=0, step=.1, title="Offset 1")
offset2 = Slider(start=-9, end=9, value=0, step=.1, title="Offset 2")

callback = CustomJS(args=dict(source=source, amp1=amp1, freq1=freq1, phase1=phase1, offset1=offset1, amp2=amp2, freq2=freq2, phase2=phase2, offset2=offset2),
                    code="""
    const A = amp1.value
    const AA = amp2.value
    const f = freq1.value
    const ff = freq2.value
    const phi = phase1.value
    const phiphi = phase2.value
    const B = offset1.value
    const BB = offset3.value

    const x = source.data.x
    const y = Array.from(x, (x) => A*Math.sin(f*x+phi)+AA*Math.sin(ff*x+phiphi)+B+BB)
    source.data = { x, y }
""")

amp1.js_on_change('value', callback)
freq1.js_on_change('value', callback)
phase1.js_on_change('value', callback)
offset1.js_on_change('value', callback)
amp2.js_on_change('value', callback)
freq2.js_on_change('value', callback)
phase2.js_on_change('value', callback)
offset2.js_on_change('value', callback)

show(row(plot, column(amp1, freq1, phase1, offset1, amp2, freq2, phase2, offset2)))

问题原因

  • JavaScript变量拼写错误:在CustomJS的代码块中,const BB = offset3.value里的offset3是不存在的变量,你定义的滑块是offset2,这个拼写错误会导致浏览器抛出ReferenceError,直接终止回调函数的执行,所以滑块调节完全无响应。
  • 潜在功能问题(非无响应直接原因):freq1和freq2的start值设为0,当滑块值为0时,Math.sin(0*x+phi)始终为0,对应的正弦项会失效,建议将start值改为0.1,避免无效计算。

修复后的代码

import numpy as np

from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, CustomJS, Slider
from bokeh.plotting import figure, show

x = np.linspace(0, 10, 500)
y = np.sin(x)

source = ColumnDataSource(data=dict(x=x, y=y))

plot = figure(y_range=(-10, 10), width=400, height=400)

plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

# 修正freq的start值为0.1,避免无效计算
amp1 = Slider(start=0, end=10, value=1, step=.1, title="Amplitude 1")
amp2 = Slider(start=0, end=10, value=0, step=.1, title="Amplitude 2")
freq1 = Slider(start=0.1, end=10, value=1, step=.1, title="Frequency 1")
freq2 = Slider(start=0.1, end=10, value=0, step=.1, title="Frequency 2")
phase1 = Slider(start=-6.4, end=6.4, value=0, step=.1, title="Phase 1")
phase2 = Slider(start=-6.4, end=6.4, value=0, step=.1, title="Phase 2")
offset1 = Slider(start=-9, end=9, value=0, step=.1, title="Offset 1")
offset2 = Slider(start=-9, end=9, value=0, step=.1, title="Offset 2")

callback = CustomJS(args=dict(source=source, amp1=amp1, freq1=freq1, phase1=phase1, offset1=offset1, amp2=amp2, freq2=freq2, phase2=phase2, offset2=offset2),
                    code="""
    const A = amp1.value
    const AA = amp2.value
    const f = freq1.value
    const ff = freq2.value
    const phi = phase1.value
    const phiphi = phase2.value
    const B = offset1.value
    // 修正拼写错误:offset3改为offset2
    const BB = offset2.value

    const x = source.data.x
    const y = Array.from(x, (x) => A*Math.sin(f*x+phi)+AA*Math.sin(ff*x+phiphi)+B+BB)
    source.data = { x, y }
""")

amp1.js_on_change('value', callback)
freq1.js_on_change('value', callback)
phase1.js_on_change('value', callback)
offset1.js_on_change('value', callback)
amp2.js_on_change('value', callback)
freq2.js_on_change('value', callback)
phase2.js_on_change('value', callback)
offset2.js_on_change('value', callback)

show(row(plot, column(amp1, freq1, phase1, offset1, amp2, freq2, phase2, offset2)))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:30:57