question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

push_notebook() does not work with ipywidgets Output Widget

See original GitHub issue

Runtime Info:

notebook server is 5.0.0 Python 3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 13:09:58) IPython 6.0.0 bokeh ‘0.12.9’ ipywidgets ‘7.0.1’ ubuntu 16

I am trying to embed bokeh plots within the ipywidgets ecosystem. However, I cannot update these plots externally when they are wrapped in an ipywidget Output Widget . Here is a simple repro

This displays the blank graph:


import bokeh
from bokeh.io import output_notebook, show, push_notebook
output_notebook(bokeh.resources.INLINE)
from bokeh.models import ColumnDataSource, Circle
import ipywidgets as widgets
from IPython.display import display


plot = figure()
source = ColumnDataSource(
    data=dict(
        x=[],
        y=[],
    )
)

circle = Circle(x="x", y="y", size=15, fill_color="blue", fill_alpha=0.8, line_color=None)
plot.add_glyph(source, circle)

outw = widgets.Output()
with outw:
    h = show(plot, notebook_handle=True)
display(outw)

This cell should update that graph:


source.data = {'x':[0], 'y':[0]}
push_notebook(handle=h);

However the first graph does not change. If I remove the wrapping in the output widget it does update. If i use an ipywidget (instead of a bokeh plot) inside of the output widget it updates as expected.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

4reactions
noobymcnoobcommented, Jan 9, 2020

Here is a full example of how to use a bokeh plot inside of a Jupyter ipywidget hierarchy:

from ipywidgets import Output
import bokeh.io as bio
import bokeh.plotting as bp
import asyncio

class BokehChartDemo(Output):
    def __init__(self, *a, **kw):
        bio.output_notebook(hide_banner=True)
        super().__init__(*a,**kw)

        self._figure = None

        asyncio.get_event_loop().create_task(self._updateLoop())

    async def _updateLoop(self):
        while True:
            # we need to wait for it to be displayed first
            await asyncio.sleep(0.25)
            self._initialize()
            self._draw()
        asyncio.get_event_loop().call_later(0.25,self._initialize)

    def _initialize(self):
        if self._figure is not None: return
        self._figure = bp.figure(sizing_mode='stretch_both')
        self._data = bp.ColumnDataSource(dict(x=[],y=[],radii=[],colours=[]))
        self._figure.circle("x","y",radius="radii",fill_color="colours",fill_alpha=0.6,line_color=None,source=self._data)

        with self:
            self._handle = bp.show(self._figure,notebook_handle=True)

    def _draw(self):
        N = 1
        x = np.random.random(size=N)*100
        y = np.random.random(size=N)*100
        radii = np.random.random(size=N)*.5
        colours = ['#%02x%02x%02x' % (r,g,150) for r,g in zip(np.floor(50+2*x).astype('int'),np.floor(30+2*y).astype('int'))]
        self._data.stream(
            dict(
                x = x,
                y = y,
                radii = radii,
                colours = colours
            ),
            1000
        )
        bio.push_notebook(handle=self._handle)

display(BokehChartDemo())
4reactions
dajurocommented, Nov 6, 2017

Hi,

I just ran into the same problem and I found a workaround: you need to render the widgets before plotting into it! This code works for me:

import bokeh
from bokeh.io import output_notebook, show, push_notebook
output_notebook(bokeh.resources.INLINE)
from bokeh.models import ColumnDataSource, Circle
import ipywidgets as widgets
from IPython.display import display

plot = figure()
source = ColumnDataSource(
    data=dict(
        x=[1],
        y=[1],
    )
)

circle = Circle(x="x", y="y", size=15, fill_color="blue", fill_alpha=0.8, line_color=None)
plot.add_glyph(source, circle)

outw = widgets.Output()

# display widget!!!!
display(outw)

# plot into widget
with outw:
    h = show(plot, notebook_handle=True)

Now you can update the plot:

source.data = {'x':[5], 'y':[5]}
push_notebook(handle=h);

Edit and FYI: this is the same for matplotlib plots as well

Read more comments on GitHub >

github_iconTop Results From Across the Web

Output widgets: leveraging Jupyter's display system - ipywidgets
The Output widget can capture and display stdout, stderr and rich output ... works well for understanding and debugging single callbacks, it does...
Read more >
Using with Jupyter — Bokeh 2.4.3 Documentation
You can use this handle object with the push_notebook() function to update the plot with any recent changes to plots properties, data source...
Read more >
IPython Notebook ipywidgets does not show - Stack Overflow
The code seem to run just fine, as the table appears, but the slide bar just doesn't appear. I didn't change my code...
Read more >
How to use ipywidgets to make your Jupyter notebook ...
Jupyter widgets can make notebooks be more interactive and make data exploration much easier, especially for end users who are not coders.
Read more >
ipywidgets | Databricks on AWS
A notebook using ipywidgets must be attached to a running cluster. Widget states are not preserved across notebook sessions. You must re-run ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found