I’m trying to update a plot using widgets with bokeh. My understanding is that bokeh’s widgets either work only with javascript updates or using the bokeh server. For those reasons I tried using ipywidgets and they somewhat work but a new plot is generated every time instead of updating the original plot. How do I achieve that?
Here’s how I tried doing it:
import bokeh.plotting as bkpl
import bokeh.io as bki
import ipywidgets as widgets
from IPython.display import display as idisplay
bki.output_notebook()
x = [1, 2, 3, 4, 5]
y = [6, 7, 2, 4, 5]
p = bkpl.figure(title="My chart", x_axis_label='x', y_axis_label='y')
p.line(x, y, legend_label="Some line", line_width=2)
def callback(evt):
bkpl.show(p)
w = widgets.Button(description='Replot')
w.on_click(callback)
display(w)
bkpl.show(p)
You’re probably looking for a pure Bokeh solution, but if you are comfortable adding a dependency on Panel, you can wrap your Bokeh figure into a Panel container like pn.Row, and then the widgets should work smoothly in or out of Jupyter. See the Panel Bokeh pane docs for details.
Huh. I do see why that would work, although to be honest it’s not what was in mind for push_notebook. All of our old examples for push_notebook are used in callbacks for ipywidgets rather than Bokeh’s widgets, since that was the original motivating use-case for push_notebook (a very long time ago now).
Just being clear, push_notebook is quite limited relative to embedded a Bokeh app in the notebook. Bokeh apps can support full two-way events between the “Python side” and the “JavaScript side”. As the name suggests, push_notebook is only capable to push updates in one direction, from Python to BokehJS.