CustomJS callback to link circle and line plots


Recently I started using Bokeh and found it a nice option. Good job guys!!

Let’s have a scatter plot (on the left) and a line plot (on the right). I would like to get a different line when I click (or even hover) on a circle on the scatter plot.

I want the similar behaviour as it is in this example:

However, now, with Bokeh 3.3.2 it doesn’t work. The error is this:

AttributeError: unexpected attribute 'callback' to ColumnDataSource, similar attributes are js_event_callbacks

When I modify the s1.callback = to s1.selected.js_on_change('indices', CustomJS(..)) I can’t get the line when I click on the circle.

Could you help me please to get the code to work?

the full code that I found in the link above is here:

import numpy
import numpy as np

import bokeh
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.layouts import column, row
from bokeh.plotting import figure, output_notebook, show

output_notebook()  # Anna: I deleted this

x = np.random.random((10,))
y = np.random.random((10,))
t = np.random.random((10,5))
tr = np.arange(t.shape[1])

s1 = ColumnDataSource(data=dict(x=x, y=y))
p1 = figure(plot_width=400, plot_height=400, tools=["tap"], title="Select Here") # Anna: from plot_width and plot_height removed the plot_'x', 'y', source=s1, alpha=0.6)

s2 = ColumnDataSource(data=dict(t=t, tr=tr, ts=[], trs=[]))
p2 = figure(plot_width=400, plot_height=400, x_range=(tr[0],tr[-1]), y_range=(t.min(),t.max()),
            tools="", title="Watch Here")
p2.line('trs', 'ts', source=s2, alpha=0.6)

s1.callback = CustomJS(args=dict(s2=s2), code="""
    var inds = cb_obj.get('selected')['1d'].indices;
    var d1 = cb_obj.get('data');
    var d2 = s2.get('data');
    d2['trs'] = [];
    d2['ts'] = [];
    for (i = 0; i < d2['tr'].length; i++) {

layout = row(p1, p2)


The ["1d"].indices style was deprecated and removed several years (and major versions) ago and will not work with Bokeh 3.x at all. Please see the documentation for a very similar modern example: CustomJS for selections. Calling the trigger method yourself should also not be needed if you follow that example.

Edit: not sure why HTML anchors don’t seem to be working on that page at the moment. The section you want is “CustomJS for selections”