CustomJS args after updating from v1.0.4

Hi all,

I recently updated bokeh from 1.0.4 to 1.2.0, and I am experiencing issues with a piece of plotting code I inherited and refined a few months back. Here is a stripped down example that reproduces my issue.

import pandas as pd
import numpy as np
from bokeh.layouts import layout
from bokeh.models import BoxSelectTool, ColumnDataSource, CustomJS
from bokeh.plotting import figure, output_file, show


output_file('bokeh_example.html')

df = pd.DataFrame(columns=['t', 'x', 'y'])
df['t'] = range(1000)
df['x'] = np.random.normal(0, 1, size=1000).cumsum()
df['y'] = np.random.normal(0, 1, size=1000).cumsum()
source = ColumnDataSource(df)

figure_kwargs = {
    "tools": [
        "reset,save",
        BoxSelectTool(dimensions="width")
    ]
}

plots = []
for feature in ['x', 'y']:
    plot = figure(title=feature, **figure_kwargs)
    plot.line('t', feature, source=source)
    plot.circle('t', feature, source=source, alpha=0)
    plots.append(plot)

callback = """\
console.log(plots);
console.log(source);
plots[0].title.text = 'changed0';
plots[1].title.text = 'changed1';\
"""
args = {'source': source, 'plots': plots}

source.selected.js_on_change('indices', CustomJS(code=callback, args=args))

show(layout(plots))

With bokeh 1.0.4, the Python and JS code work as expected. In bokeh 1.1.0/1.2.0, the resulting HTML file is empty, and this error is present in the console.

I believe the issue is specific to the passing of plots as an argument to the callback. If I change callback and args to the following

callback = """\
console.log(source);\
"""
args = {'source': source}

then the HTML file does render the two figures and the (now limited) callback works as expected.

I’ve read the migration guide for 1.0.4 and later, but nothing struck me as being related to this issue. I appreciate your help. Thanks!

–Brent

This appears to be a bug specific to passing plots in args. Please file a GitHub bug report issue with this information.

In the mean time, this works for me with Bokeh 1.2

callback = """
console.log(source);
titles[0].text = 'changed0';
titles[1].text = 'changed1';
"""

args = {'source': source, 'titles': [x.title for x in plots]}

Bryan,

I verified that passing a list of titles works for me. I’m ultimately interested in accessing the the renderers, and it seems the solution you’ve proposed for titles does not work (i.e. 'renderers': [plot.renderers for plot in plots]). There is a failure similar to what is seen when plots is passed.

I’ll write up a Github issue with all of this information as you proposed.

Thanks a bunch for your help!

1 Like