5

I want to use bokeh widgets from within a jupyter notebook to update a bokeh plot. My (somewhat hacky) code looks like this:

from bokeh.plotting import figure
from bokeh.io import output_notebook, push_notebook, show
from bokeh.models import CustomJS, Slider

output_notebook()

power = 0.5
x = [1,2,3]
y = [i**power for i in x]

fig = figure()
plt = fig.circle(x, y)

def update_plot(power):
    x = plt.data_source.data['x']
    plt.data_source.data['y'] = [i**power for i in x]
    push_notebook(handle=bokeh_handle)  


bokeh_handle = show(fig, notebook_handle=True)

##### new notebook cell #####

callback = CustomJS(code="""
if (IPython.notebook.kernel !== undefined) {
    var kernel = IPython.notebook.kernel;
    cmd = "update_plot(" + cb_obj.value + ")";
    kernel.execute(cmd, {}, {});
}
""")

slider = Slider(start=0.1, 
                end=1,
                value=1,
                step=.05,
                title="power",
                callback=callback)
show(slider)

The idea is that the JS callback for the slider calls the python function update_plot(), which changes the data of the bokeh plot and then triggers a push_notebook().

However, when I move the slider, the plot is not updated, but some weird glyphs appear in the upper left corner (see red arrow).

Executing print(plt.data_source.data['y']) showed me that the callback and update_plot() were actually called upon slider movement. Why is the plot not properly updated? Or am I missing something here?

(I know that I can do the same thing using ipywidgets.interact, but I want to stick to bokeh widgets.)

2
  • I can reproduce this, it seems like there might be a problem with update events (i.e. push_notebook) coming mid-flight during another ongoing event processing (the slider callback). The "weird glyph" is actually the entire plot shrunk down to the minimum canvas size (20x20px I think). I'd suggest filing an issue on the GitHub issue tracker with this information. Commented Nov 10, 2016 at 18:48
  • Thx, the issue is up Commented Nov 10, 2016 at 22:12

1 Answer 1

6

I got the plot to update as expected by displaying the figure and the slider widget within a bokeh.layouts.row layout:

from bokeh.plotting import figure
from bokeh.io import output_notebook, push_notebook, show
from bokeh.models import CustomJS, Slider
from bokeh.layouts import row

output_notebook()

power = 0.5
x = [1,2,3]
y = [i**power for i in x]

fig = figure()
plt = fig.circle(x, y)

def update_plot(power):
    x = plt.data_source.data['x']
    plt.data_source.data['y'] = [i**power for i in x]
    push_notebook(handle=bokeh_handle)  


##### new notebook cell #####

callback = CustomJS(code="""
if (IPython.notebook.kernel !== undefined) {
    var kernel = IPython.notebook.kernel;
    cmd = "update_plot(" + cb_obj.value + ")";
    kernel.execute(cmd, {}, {});
}
""")

slider = Slider(start=0.1, 
                end=1,
                value=1,
                step=.05,
                title="power",
                callback=callback)
bokeh_handle = show(row(fig, slider), notebook_handle=True)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.