Search code examples
jupyter-notebookbokeh

How can the data from points drawn with Bokeh PointDrawTool be accessed in other cells of a jupyter notebook?


I'm trying to draw two points in a Bokeh figure with the PointDrawTool in one cell of a jupyter notebook and then in a different cell, use the coordinates of the drawn points.

I started with this example:

https://docs.bokeh.org/en/latest/docs/user_guide/examples/tools_point_draw.html

... and modified it slightly to output inside the notebook:

from bokeh.plotting import figure, output_file, show, Column
from bokeh.models import DataTable, TableColumn, PointDrawTool, ColumnDataSource
from bokeh.io import output_notebook
output_notebook()


p = figure(
           title='scope')
p.background_fill_color = 'lightgrey'

source = ColumnDataSource({
    'x': [1, 5, 9], 'y': [1, 5, 9], 'color': ['red', 'green', 'yellow']
})

renderer = p.scatter(x='x', y='y', source=source, color='color', size=10)
columns = [TableColumn(field="x", title="x"),
           TableColumn(field="y", title="y"),
           TableColumn(field='color', title='color')]
table = DataTable(source=source, columns=columns, editable=True, height=200)

draw_tool = PointDrawTool(renderers=[renderer], empty_value='black')
p.add_tools(draw_tool)
p.toolbar.active_tap = draw_tool
#p.line(range(len(y)),y)

show(Column(p, table))

I draw two points in the plot.

In another notebook cell:

len(source.data["x"]) 

It returns 3. In other words, I can access the three points that 'source' was initialized with but not any points that were drawn afterwards.

Any ideas?


Solution

  • If you want full two-way synchronization and communication, that requires embedding a Bokeh server application. Calling show with plain Bokeh objects as you have done above only results in a one-time output of Bokeh JS content, with no further communication to Python. Embedding a Bokeh Server app typically involves defining a function modify_doc(doc) that can create a new bokeh server session whenever show(modify_doc) is called. You can see a complete example notebook with more explanation here:

    https://github.com/bokeh/bokeh/blob/0.13.0/examples/howto/server_embed/notebook_embed.ipynb

    For your code, an updated working version looks like this:

    enter image description here

    IT IS VERY IMPORTANT TO NOTE: Any Bokeh objects for the app, e.g. data sources, must only be created inside modify_doc. You typically cannot create or refer to Bokeh objects directly outside of modify_doc. All synchronization to "outside" the app must be explicit. E.g. you could define a callback on the data source in modify_doc that updates some mutable data structure in another cell, if you wanted.