pythonplotbokeh

Two similar codes but one does not work (Bokeh for Python)


I have two different but similar codes in python that use Bokeh to make an interactive plot. The following code works fine (I found it online).

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)))

However the next one does produce a plot but the sliders do not respond.

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)))

The second plotted function is a bit more complicated but it should work. Why does it not work?

There is not really anything I could try other than checking my code for typos.


Solution

  • in the second code change

    const BB = offset3.value
    

    to

    const BB = offset2.value