Jupyter notebooks are computable documents often used for exploratory work,
data analysis, teaching, and demonstration. A notebook is a series of input
cells that can execute individually to immediately display their output. In
addition to Classic notebooks, there are also notebooks for the newer
JupyterLab project. Bokeh can embed both standalone and Bokeh server content
Standalone Bokeh content doesn’t require a Bokeh server and can be embedded
directly in classic Jupyter notebooks as well as in JupyterLab.
To display Bokeh plots inline in a classic Jupyter notebook, use the
output_notebook() function from bokeh.io instead of (or in addition to)
the output_file() function. No other modifications are required. When you
call show(), the plot will display inline in the next notebook output cell.
See a screenshot of Jupyter below:
To have a single notebook output cell display multiple plots, call show()
multiple times in the input cell. The plots will display in order.
To embed Bokeh plots in JupyterLab, you’ll need the following two JupyterLab extensions:
First install jupyterlab-manager with this command:
jupyter labextension install @jupyter-widgets/jupyterlab-manager
Then install the jupyter_bokeh extension as follows:
jupyter labextension install @bokeh/jupyter_bokeh
The rest is the same as with classic notebooks above.
You can also embed full Bokeh server applications connecting plot events
and Bokeh’s built-in widgets directly to Python callback code.
See Running a Bokeh server for general information about Bokeh server
applications. For a complete example of a Bokeh application embedded in
a Jupyter notebook, refer to the following notebook:
When running notebooks from your own JupyterHub instance, some additional
steps are necessary to embed Bokeh server applications and to enable network
connectivity between the client browser and the Bokeh server running in a
JupyterLab cell. This is because your browser needs to connect to the port the
Bokeh server is listening on. However, JupyterHub is acting as a reverse proxy
between your browser and your JupyterLab container. Follow all the JupyterLab
instructions above, then continue with the following steps:
Install the nbserverproxy server extension as follows:
pip install nbserverproxy && jupyter serverextension enable --py nbserverproxy
Define a function to help create the URL for the browser to connect to
the Bokeh server.
See below for a reference implementation. You’ll have to either modify
this code or assign the URL of your JupyterHub installation to the environment
variable EXTERNAL_URL. JupyterHub defaults to JUPYTERHUB_SERVICE_PREFIX
in this case.
Callable to configure Bokeh's show method when a proxy must be
If port is None we're asking about the URL
for the origin header.
base_url = os.environ['EXTERNAL_URL']
host = urllib.parse.urlparse(base_url).netloc
# If port is None we're asking for the URL origin
# so return the public hostname.
if port is None:
service_url_path = os.environ['JUPYTERHUB_SERVICE_PREFIX']
proxy_url_path = 'proxy/%d' % port
user_url = urllib.parse.urljoin(base_url, service_url_path)
full_url = urllib.parse.urljoin(user_url, proxy_url_path)
Pass the function you defined in step 2 to the show() function
as the notebook_url keyword argument. Bokeh then calls this
function when it sets up the server and creates the URL to load a graph:
Now the Bokeh graph should load and execute Python
callbacks defined in your JupyterLab environment.
Depending on the version of the notebook you are using, you may have to
trust the notebook
for Bokeh plots to re-render when the notebook is closed and re-
opened. The Trust Notebook option is typically located under the
You can use a notebook with Reveal.js to generate slideshows from cells.
You can also include standalone (i.e. non-server) Bokeh plots in such sideshows.
However, you will need to take a few extra steps to display the output correctly.
Particularly, make sure that the cell containing the output_notebook
is not be skipped.
Rendered cell output of the output_notebook call ensures that the
BokehJS library loads. Otherwise, Bokeh plots will not work. If this cell’s
type is set to “skip”, BokehJS will not load, and Bokeh plots will not display.
If you want to hide this cell, assign it the “notes” slide type.
You can update a displayed plot without reloading it. To do so, pass the
notebook_handle=True argument to show() for it to return a handle object.
You can use this handle object with the push_notebook() function to update the plot
with any recent changes to plots properties, data source values, etc.
This notebook handle functionality is only supported in classic Jupyter notebooks
and is not implemented in JupyterLab or Zeppelin yet.
The following screenshots illustrate basic usage of notebook handles:
Import standard functions and push_notebook():
Create some plots and pass notebook_handle=True to show():
Check that the handle is associated with the output cell for In just displayed:
Update some properties of the plot, then call push_notebook() with the handle:
Note that the output cell for In has changed (without being re-executed):
See the following notebooks for more detailed examples of notebook handle use:
examples/howto/notebook_comms/Numba Image Example.ipynb
You can use notebook widgets, known as interactors, to update
Bokeh plots. The key to doing this is the push_notebook() function.
The update callback for the interactors calls this function
to update the plot from widget values. See a screenshot of the
examples/howto/notebook_comms/Jupyter Interactors.ipynb example
You can find many more examples of notebook use in the bokeh-notebook repository:
Clone the repository locally:
git clone https://github.com/bokeh/bokeh-notebooks.git
Launch the Jupyter notebooks in your web browser.
Alternatively, Binder hosts live notebooks that you can run online.
The main Bokeh repository also includes some notebooks under examples:
range update callback
embed server in notebook
US marriages and divorces interactive
Notebook comms examples:
Numba image example
Now that you know how to use Bokeh in the JupyterLab and classical notebook environments,
you might want to take advantage of the vibrant Jupyter ecosystem outside of these environments.
You can do so with the ipywidgets_bokeh extension for Bokeh:
$ conda install -c bokeh ipywidgets_bokeh
$ pip install ipywidgets_bokeh
This extension lets you use IPyWidgets in Bokeh. Simply wrap a widget in an
IPyWidget model and add the wrapper to a document or include it in a layout.
You don’t have to install or enable any other extensions.
Follow these steps to build an application with a single Jupyter slider that
logs its adjustments to the console:
Start by constructing a widget and configuring an observer:
from ipywidgets import FloatSlider
angle = FloatSlider(min=0, max=360, value=0, step=1, description="Angle")
To integrate the widget with Bokeh, wrap it in IPyWidget:
from ipywidgets_bokeh import IPyWidget
ipywidget = IPyWidget(widget=angle)
Add the wrapper to a Bokeh document:
from bokeh.plotting import curdoc
doc = curdoc()
To run the app, enter bokeh serve ipy_slider.py, where ipy_slider.py
is the name of the application (see Running a Bokeh server for details).
This application is available at http://localhost:5006/ipy_slider.
bokeh serve ipy_slider.py
You can build on the above to create more complex layouts and include advanced widgets,
such as ipyleaflet and ipyvolume. For more examples, see examples/howto/ipywidgets
in the Bokeh repository.