I have a very long mathematical formula expression (sympy_expr, obtained from Sympy) with a few free parameters. I want to make an interactive Bokeh widget with a few sliders for tuning of the free parameters, similarly to the example code below but with my long mathematical formula from Sympy instead of A*Math.sin(x[i])
. I know how to convert the Sympy expression to a string in JS-format with jscode(sympy_expr)
. I do not know how to include the expression in the CustomJS callback function automatically (without copy-pasting, which would be horrible for readability). I am working with jupyter-notebook and would also be open to a jupyter-notebook solution. However, I'd prefer a html solution.
import numpy as np
from bokeh.layouts import column, row
from bokeh.models import CustomJS, Slider
from bokeh.plotting import ColumnDataSource, figure, show
x = np.linspace(0, 10, 500)
y = np.sin(x)
source = ColumnDataSource(data=dict(x=x, y=y))
plot = figure()
plot.line('x', 'y', source=source)
amp_slider = Slider(start=0.1, end=10, value=1, step=.1)
callback = CustomJS(args=dict(source=source, amp=amp_slider),
code="""
const data = source.data;
const A = amp.value;
const x = data['x']
const y = data['y']
for (let i = 0; i < x.length; i++) {
y[i] = A*Math.sin(x[i]);
}
source.change.emit();
""")
amp_slider.js_on_change('value', callback)
layout = row(
plot,
column(amp_slider),
)
show(layout)
Of course, I could make a python string code_str
of the JS-code
code_str = 'const data = source.data; const A = amp.value; const x = data[\"x\"]; const y = data[\"y\"] for (let i = 0; i < x.length; i++) {y[i] = A*Math.sin(x[i]);}source.change.emit();'
and substitute the A*Math.sin(x[i])
segment with the math formula string jscode(sympy_expr)
from Sympy, but that solution seems icky.