I have some unusual behavior when updating Bokeh models in a notebook, in the case that a callback updates a data source which itself has an on_change
callback registered.
The example case:
- One button and two plots, with one CDS each
- The button callback updates the first CDS data
- The first CDS data has a Bokeh
on_change
callback which updates the second CDS data
The behaviour: if I add a pn.io.push_notebook
to the button callback, the first plot updates (only); if I skip the pn.io.push_notebook
in the button callback the second plot updates (only), I think due to the wrapped callbacks on pn.pane.Bokeh
. If I disable pn.pane.Bokeh(autodispatch=False)
, nothing updates (unsurprising).
The example is intended as a notebook cell, but runs as intended as a script by adding a .show()
at the end.
import panel as pn
pn.extension()
import numpy as np
from bokeh.models import ColumnDataSource
from bokeh.plotting.figure import figure
from bokeh.models.glyphs import Scatter
def new_data(n_pts=10):
return {
'x': np.random.randint(0, 10, size=(n_pts,)),
'y': np.random.randint(0, 10, size=(n_pts,)),
}
def get_scatter():
fig = figure(width=400, height=300)
glyph = Scatter(marker='circle', size=10, line_color=None, fill_color='red')
cds = ColumnDataSource(new_data())
renderer = fig.add_glyph(cds, glyph)
pane = pn.pane.Bokeh(fig)
return pane, cds
pane0, cds0 = get_scatter()
pane1, cds1 = get_scatter()
new_scatter_btn = pn.widgets.Button(name='New data', width=200)
def update_first(*e):
cds0.data.update(new_data())
# if uncommented, first plot is updated instead of second
# pn.io.push_notebook(pane0)
new_watcher = new_scatter_btn.on_click(update_first)
def update_second(attr, old, new):
cds1.data.update(new_data())
cds0.on_change('data', update_second)
lo = pn.Column(new_scatter_btn, pn.Row(pane0, pane1))
lo
I may be trying to do something which is unsupported here, but it’s a pattern I have come to rely on in the panel serve
context, it would be great if anyone has any ideas of how to do this in a notebook also.
Panel 0.14.3 / Bokeh 2.4.3 / Python 3.10.9