Expected behavior
In Bokeh 1.4.0, I have a CustomJS callback function that works well but does not work in 2.x.x. In the callback, I am summing detector signals stored in a ColumnDataSource and updating the displayed image using a callback triggered by a CheckboxButtonGroup.
Observed behavior
In 2.x.x when the callback executes the source.change.emit() line I get an Uncaught RangeError: “Maximum call stack size exceeded” in the js console. It appears that the typed array for Bokeh has changed, but I don’t know how to effect the same behaviour in this version. i.e. I don’t know how to construct an appropriate array for the update.
Example code
import numpy as np
from bokeh.plotting import Figure, show, output_notebook()
from bokeh.models import ColumnDataSource, CheckboxButtonGroup, CustomJS
from bokeh.layouts import column
output_notebook()
det1 = np.zeros((1000,256))
np.fill_diagonal(det1, 5)
det2 = np.empty((256, 1000))
np.fill_diagonal(det2, 3)
data = {'x': np.linspace(270, 320, 1000),
'y': np.linspace(0, 2560, 256),
'image': det1,
'det1': det1,
'det2': det2,
'det3': np.ones((1000, 256)),
'det4': np.zeros((1000, 256)) -0.5
}
delta = max(data['x']) - min(data['x'])
bins = max(data['y']) - min(data['y'])
source = ColumnDataSource(dict(image=[data['image'].T],
det1=[data['det1'].T],
det2=[data['det2']],
det3=[data['det3'].T],
det4=[data['det4'].T],
x=[min(data['x'])],
y=[min(data['y'])],
delta=[delta],
bins=[bins]))
plot = Figure(plot_width=600, plot_height=600, tools="box_select,save,box_zoom, wheel_zoom,hover,pan,reset")
plot.image(image='image', y='y', x='x', dh='bins', dw='delta', source=source,
palette="Spectral11")
select = CheckboxButtonGroup(name="Detector Select:", labels=['1', '2', '3', '4'], active=[0])
callback_str = """
var d1 = source.data['det1'][0];
var d2 = source.data['det2'][0];
var d3 = source.data['det3'][0];
var d4 = source.data['det4'][0];
var d = source.data['image'];
var sum = new Array();
function sumArrays(...arrays) {
const n = arrays.reduce((max, xs) => Math.max(max, xs.length), 0);
const result = Float64Array.from({ length: n });
return result.map((_, i) => arrays.map(xs => xs[i] || 0).reduce((sum, x) => sum + x, 0));
}
var f = cb_obj.active;
if (f.indexOf(0) > -1) {
sum.push(d1);
}
if (f.indexOf(1) > -1) {
sum.push(d2);
}
if (f.indexOf(2) > -1) {
sum.push(d3);
}
if (f.indexOf(3) > -1) {
sum.push(d4);
}
d[0] = sumArrays(...sum);
//Everything above works fine, error occurs during update of source.data['image'].
source.change.emit();
"""
select_callback = CustomJS(args=dict(source=source), code=callback_str)
select.js_on_change('active', select_callback)
layout = column(select, plot)
show(layout)
Posted on StackOverflow