Bokeh in widget layouts

I’m trying to find a good way of embedding Bokeh-charts in widget-layouts. So far I have this:

import ipywidgets as widgets
from bokeh.io import push_notebook, show, output_notebook
import bokeh.plotting as plt
output_notebook()

class FigureContext(widgets.Output):
    def __init__(self, fig=None):
        super().__init__()
        if fig is not None:
            self.set_figure(fig)
    
    def set_figure(self, fig):
        self._figure = fig
        self.on_displayed(lambda x: x.set_handle())
        
    def set_handle(self):
        self.clear_output()
        with self:
            self._handle = show(self.get_figure(), notebook_handle=True)
        
    def get_handle(self):
        return self._handle

    def get_figure(self):
        return self._figure

    def update(self):
        push_notebook(handle=self._handle)

def figure(*args, **kwargs):
    fig = plt.figure(*args, **kwargs)
    return FigureContext(fig)

This works if I do e.g.

box = widgets.HBox([figure()])
box

But not if I do:

box = widgets.HBox()
box

and then

box.children = [figure()]

Do you know what the problem might be?

It seems that panel has this functionality built in:

import bokeh.plotting as plt
import panel as pn
fig = plt.figure()
fw = pn.ipywidget(fig)
2 Likes