So far we have seen how to generate interactive Bokeh output directly inline in Jupyter notbeooks. It also possible to embed interactive Bokeh plots and layouts in other contexts, such as standalone HTML files, or Jinja templates. Additionally, Bokeh can export plots to static (non-interactive) PNG and SVG formats.
We will look at all of these possibilities in this chapter. First we make the usual imports.
from bokeh.io import output_notebook, show
output_notebook()
And also load some data that will be used throughout this chapter
import pandas as pd
from bokeh.plotting import figure
from bokeh.sampledata.stocks import AAPL
df = pd.DataFrame(AAPL)
df['date'] = pd.to_datetime(df['date'])
To start we will look different ways of embedding live interactive Bokeh output in various situations.
The first way to embed Bokeh output is in the Jupyter Notebooks, as we have already, seen. As a reminder, the cell below will generate a plot inline as output, because we executed output_notebook
above.
p = figure(width=800, height=250, x_axis_type="datetime")
p.line(df['date'], df['close'], color='navy', alpha=0.5)
show(p)
It is also often useful to generate a standalone HTML script containing Bokeh content. This is accomplished by calling the output_file(...)
function. It is especially common to do this from standard Python scripts, but here we see that it works in the notebook as well.
from bokeh.io import output_file, show
output_file("plot.html")
show(p) # save(p) will save without opening a new browser tab
In addition the inline plot above, you should also have seen a new browser tab open with the contents of the newly saved "plot.html" file. It is important to note that output_file
initiates a persistent mode of operation. That is, all subsequent calls to show will generate output to the specified file. We can "reset" where output will go by calling reset_output
:
from bokeh.io import reset_output
reset_output()
Another use case is to embed Bokeh content in a Jinja HTML template. We will look at a simple explicit case first, and then see how this technique might be used in a web app framework such as Flask.
The simplest way to embed standalone (i.e. not Bokeh server) content is to use the components
function. This function takes a Bokeh object, and returns a <script>
tag and <div>
tag that can be put in any HTML tempate. The script will execute and load the Bokeh content into the associated div.
The cells below show a complete example, including loading BokehJS JS and CSS resources in the template.
import jinja2
from bokeh.embed import components
# IMPORTANT NOTE!! The version of BokehJS loaded in the template should match
# the version of Bokeh installed locally.
template = jinja2.Template("""
<!DOCTYPE html>
<html lang="en-US">
<link
href="http://cdn.pydata.org/bokeh/dev/bokeh-0.13.0.min.css"
rel="stylesheet" type="text/css"
>
<script
src="http://cdn.pydata.org/bokeh/dev/bokeh-0.13.0.min.js"
></script>
<body>
<h1>Hello Bokeh!</h1>
<p> Below is a simple plot of stock closing prices </p>
{{ script }}
{{ div }}
</body>
</html>
""")
p = figure(width=800, height=250, x_axis_type="datetime")
p.line(df['date'], df['close'], color='navy', alpha=0.5)
script, div = components(p)
from IPython.display import HTML
HTML(template.render(script=script, div=div))
Note that it is possible to pass multiple objects to a single call to components
, in order to template multiple Bokeh objects at once. See the User's Guide for components for more information.
Once we have the script and div from components
, it is straighforward to serve a rendered page containing Bokeh content in a web application, e.g. a Flask app as shown below.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_bokeh():
return template.render(script=script, div=div)
# Uncomment to run the Flask Server. Use Kernel -> Interrupt from Notebook menubar to stop
#app.run(port=5050)
# EXERCISE: Create your own template (or modify the one above)
Sometimes it is desirable to produce static images of plots or other Bokeh output, without any interactive capabilities. Bokeh supports exports to PNG and SVG formats.
Bokeh supports exporting a plot or layout to PNG image format with the export_png
function. This function is alled with a Bokeh object to export, and a filename to write the PNG output to. Often the Bokeh object passed to export_png
is a single plot, but it need not be. If a layout is exported, the entire layout is saved to one PNG image.
*Important Note:* the PNG export capability requires installing some additional optional dependencies. The simplest way to obtain them is via conda:
conda install selenium phantomjs pillow
from bokeh.io import export_png
p = figure(width=800, height=250, x_axis_type="datetime")
p.line(df['date'], df['close'], color='navy', alpha=0.5)
export_png(p, filename="plot.png")
from IPython.display import Image
Image('plot.png')
# EXERCISE: Save a layout of plots (e.g. row or column) as SVG and see what happens
Bokeh can also generate SVG output in the browser, instead of rendering to HTML canvas. This is accomplished by setting output_backend='svg'
on a figure. This can be be used to generate SVGs in output_file
HTML files, or in content emebdded with components
. It can also be used with the export_svgs
function to save .svg
files. Note that an SVG is created for each canvas. It is not possible to capture entire layouts or widgets in SVG output.
*Important Note:* There a currently some known issue with SVG output, it may not work for all use-cases
from bokeh.io import export_svgs
p = figure(width=800, height=250, x_axis_type="datetime", output_backend='svg')
p.line(df['date'], df['close'], color='navy', alpha=0.5)
export_svgs(p, filename="plot.svg")
from IPython.display import SVG
SVG('plot.svg')
# EXERCISE: Save a layout of plots (e.g. row or column) as SVG and see what happens
Click on this link to go to the next notebook: 11 - Running Bokeh Applications.
To go back to the overview, click here.