两段相似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
相关产品推荐
相关产品推荐

