Here is how you can do it without using a Bokeh server. Make sure the data you want to update is in a ColumnDataSource
you explicitly create, and make sure to set a name
property on the CDS (can be whatever you want):
from bokeh.io import show
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
x = [1, 2, 3, 4, 5]
y = [6, 7, 6, 4, 5]
source = ColumnDataSource(data=dict(x=x, y=y), name="MY_SOURCE")
p = figure(plot_width=300, plot_height=300)
p.line('x', 'y', source=source)
show(p)
That produces this:
Now in yout JavaScript event handlers, you can access the global Bokeh.index
and use it to obtain the CDS you named, and update it:
The Bokeh.index
is a “dict” that maps ids to Bokeh views, each of which has a model
that corresponds the the Python side Bokeh object. In this case, the single Figure
that was shown. The models also have a select_one
method that lets you search for children objects by name (i.e. "MY_SOURCE"
in this case). Once you have that data source, you can update it by re-assigning to source.data
and the plot will update (you have to make a real assignment, if you update the data arrays “in place” then BokehJS won’t be able to pick up the change automatically).
If you have multiple plots/layouts on the same page you will have potentially need to look through all of the views in Bokeh.index
to find what you are looking for. This is all a bit clunky which is why it has not been demonstrated widely.
Note: the JavaScript objects look fairly obfuscated because BokehJS is “minified” by default, to save space. For testing, you can set the environment variable BOKEH_MINIFIED=no
and you will see much more human-readable output in the console.