In [1]:
from bokeh.plotting import figure, output_file, show

In [2]:
output_file("test.html")

In [3]:
p = figure()

In [4]:
print(type(p))


<class 'bokeh.plotting.figure.Figure'>

In [5]:
p.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=2)


Out[5]:
GlyphRenderer(
id = '1038', …)

In [6]:
show(p)

In [14]:
# Standard imports
from bokeh.io import output_notebook, show

In [2]:
output_notebook()


Loading BokehJS ...

In [3]:
# Plot a complex chart with interactive hover in a few lines of code

In [5]:
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.plotting import figure
from bokeh.sampledata.autompg import autompg_clean as df
from bokeh.transform import factor_cmap

In [6]:
df.cyl = df.cyl.astype(str)
df.yr = df.yr.astype(str)

In [7]:
group = df.groupby(by=['cyl', 'mfr'])
source = ColumnDataSource(group)

In [8]:
p = figure(plot_width=800, plot_height=300, title="Mean MPG by # Cylinders and Manufacturer",
          x_range=group, toolbar_location=None, tools="")

In [9]:
p.xgrid.grid_line_color = None
p.xaxis.axis_label = "Manufacturer grouped by # Cylinders"
p.xaxis.major_label_orientation = 1.2

In [10]:
index_cmap = factor_cmap('cyl_mfr', palette=['#2b83ba', '#abdda4', '#ffffbf', '#fdae61', '#d7191c'],
                        factors=sorted(df.cyl.unique()), end=1)

In [11]:
p.vbar(x='cyl_mfr', top='mpg_mean', width=1, source=source,
      line_color="white", fill_color=index_cmap,
      hover_line_color="darkgrey", hover_fill_color=index_cmap)


Out[11]:
GlyphRenderer(
id = '1029', …)

In [12]:
p.add_tools(HoverTool(tooltips=[("MPG", "@mpg_mean"), ("Cyl, Mfr", "@cyl_mfr")]))

In [15]:
show(p)



In [16]:
from IPython.display import IFrame

In [18]:
IFrame('https://demo.bokehplots.com/apps/sliders', width=900, height=500)


Out[18]:

In [19]:
from IPython.core.display import Markdown

In [20]:
Markdown(open("README.md").read())


---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-20-fc345002c984> in <module>
----> 1 Markdown(open("README.md").read())

FileNotFoundError: [Errno 2] No such file or directory: 'README.md'

In [21]:
from IPython import __version__ as ipython_version
from pandas import __version__ as pandas_version
from bokeh import __version__ as bokeh_version

In [22]:
print("IPython - %s" % ipython_version)
print("Pandas - %s" % pandas_version)
print("Bokeh - %s" % bokeh_version)


IPython - 7.4.0
Pandas - 0.23.4
Bokeh - 1.0.4

In [23]:
from bokeh.plotting import figure, output_file, show

Basic steps to creating plots with bokeh.plotting interface are:

Prepare some data

In this case, plain python lists, but oculd also be NumPy arrays or Pandas series.


In [24]:
# prepare some data
x = [1, 2, 3, 4, 5]
y = [6, 7, 2, 4, 5]

Tell Bokeh where to generate output

In this case, using output_file(), with filename "lines.html". Another option is output_notebook() for use in Jupyter notebooks.


In [25]:
# output to static HTML file
output_file("lines.html")

Call figure()

This creates a plot with typical default options and easy customization of title, tools, and axes labels.


In [26]:
# create a new plot with a title and axis labels
p = figure(title="simple line example", x_axis_label='x', y_axis_label='y')

Add renderers

In this case, we use line() for our data, specifying visual customizations like colors, legends, and widths.


In [27]:
# add a line renderer with legend and line thickness
p.line(x, y, legend="Temp.", line_width=2)


Out[27]:
GlyphRenderer(
id = '1123', …)

Ask Bokeh to show() or save() the results. These functions save plot to an HTML file and optionally display it in a browser.


In [28]:
# show the results
show(p)


Steps 3 and 4, "Add renderers", "Ask Bokeh to show() or save() the results", can be repeated to create more than 1 plot.


In [29]:
from bokeh.plotting import figure, output_file, show

In [30]:
# prepare some data
x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
y0 = [i**2 for i in x]
y1 = [10**i for i in x]
y2 = [10**(i**2) for i in x]

In [31]:
# output to static HTML file
output_file("log_lines.html")

In [32]:
# create new plot
p = figure(
    tools="pan,box_zoom,reset,save",
    y_axis_type="log", y_range=[0.001, 10**11], title="log axis example",
    x_axis_label='sections', y_axis_label='particles')

In [33]:
# add some renderers
p.line(x, x, legend="y=x")
p.circle(x, x, legend="y=x", fill_color="white", size=8)
p.line(x, y0, legend="y=x^2", line_width=3)
p.line(x, y1, legend="y=10^x", line_color="red")
p.circle(x, y1, legend="y=10^x", fill_color="red", line_color="red", size=6)
p.line(x, y2, legend="y=10^x^2", line_color="orange", line_dash="4 4")


Out[33]:
GlyphRenderer(
id = '1385', …)

In [34]:
# show the results
show(p)



In [35]:
from bokeh.plotting import output_notebook

To view examples in a notebook, you'd only change output_file() to a call to output_notebook() instead.


In [36]:
output_notebook()


Loading BokehJS ...

Vectorized colors and sizes

This example shows how it's possible to provide sequences of data values for glyph attributes like fill_color, radius.


In [2]:
import numpy as np

In [3]:
from bokeh.plotting import figure, output_file, show

In [4]:
# prepare some data
N = 4000
x = np.random.random(size = N) * 100
y = np.random.random(size = N) * 100
radii = np.random.random(size = N) * 1.5

In [5]:
colors = ["#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50 + 2 * x, 30 + 2 * y)] # rainbox colors

In [7]:
print(len(colors))


4000

In [8]:
# output to static HTML file (with CDN resources)
output_file("color_scatter.html", title="color_scatter.py example", mode = "cdn")

In [9]:
TOOLS = "crosshair,pan,wheel_zoom,box_zoom,reset,box_select,lasso_select"
  • supplying an explicit list of tool names to figure()
  • fetching BokehJS resources from CDN using the mode argument
  • setting the x_range and y_range explicitly
  • using NumPy arrays for supplying data

In [10]:
# create a new plot with the tools above, and explicit ranges
p = figure(tools=TOOLS, x_range=(0, 100), y_range=(0, 100))

In [11]:
# add a circle renderer with vectorized colors and sizes
p.circle(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None)


Out[11]:
GlyphRenderer(
id = '1044', …)

In [12]:
# show the results
show(p)

Linked panning and brushing

Linking together various aspects of different plots - such linkages are typically sharing some plot component between plots.

Below is an example of linked panning (where changing the range of one plot causes others to update) by

  • sharing range objects between the plots.

In [13]:
from bokeh.layouts import gridplot
from bokeh.plotting import figure, output_file, show

In [14]:
# prepare some data
N = 100
x = np.linspace(0, 4*np.pi, N)
y0 = np.sin(x)
y1 = np.cos(x)
y2 = np.sin(x) + np.cos(x)

In [15]:
# output to static HTML file
output_file("linked_panning.html")
  • calling figure() multiple times to create multiple plots
  • showing new glyphs using new glyph methods triangle() and square()

In [16]:
# create a new plot
s1 = figure(width=250, plot_height=250, title=None)
s1.circle(x, y0, size=10, color="navy", alpha=0.5)


Out[16]:
GlyphRenderer(
id = '1175', …)

In [17]:
# NEW: create a new plot and share both ranges (in x and y directions)
s2 = figure(width=250, height=250, x_range=s1.x_range, y_range=s1.y_range, title=None)
s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5)


Out[17]:
GlyphRenderer(
id = '1215', …)

In [18]:
# NEW: create a new plot and share only one range (in x-direction)
s3 = figure(width=250, height=250, x_range=s1.x_range, title=None)
s3.square(x, y2, size=10, color="olive", alpha=0.5)


Out[18]:
GlyphRenderer(
id = '1256', …)
  • using gridplot() to arrange several plots in an array
  • hiding the toolbar by setting toolbar_location to None
  • setting convenience arguments color (sets both line_color and fill_color) and alpha (sets both line_alpha and fill_alpha)

In [19]:
p = gridplot([[s1, s2, s3]], toolbar_location=None)

In [20]:
# show the results
show(p)

linked brushing - where selection on 1 plot causes a selection to update on other plots.

Below, linked brushing is by sharing a ColumnDataSource between 2 plots.


In [21]:
from bokeh.plotting import *
from bokeh.models import ColumnDataSource

In [23]:
# prepare some data
N = 300
x = np.linspace(0, 4*np.pi, N)
y0 = np.sin(x)
y1 = np.cos(x)

In [24]:
# output to static HTML file
output_file("linked_brushing.html")

In [25]:
# NEW: create a column data source for the plots to share
source = ColumnDataSource(data=dict(x=x, y0=y0, y1=y1))

In [26]:
TOOLS = "pan,wheel_zoom,box_zoom,reset,save,box_select,lasso_select"

In [27]:
# create a new plot and add a renderer
left = figure(tools=TOOLS, width=350, height=350, title=None)

In [28]:
left.circle('x', 'y0', source=source)


Out[28]:
GlyphRenderer(
id = '1527', …)

In [29]:
# create another new plot and add a renderer
right = figure(tools=TOOLS, width=350, height=350, title=None)
right.circle('x', 'y1', source=source)


Out[29]:
GlyphRenderer(
id = '1575', …)

In [30]:
# put the subplots in a gridplot
p = gridplot([[left, right]])

In [31]:
# show the results
show(p)

Datetime axes

DatetimeAxis that can change displayed ticks based on current scale of the plot. There are some inputs for which Bokeh will automatically default to DatetimeAxis, but you can always explicitly ask for one by passing the value "datetime" to the x_axis_type or y_axis_type parameters to figure().


In [32]:
from bokeh.sampledata.stocks import AAPL

In [33]:
# prepare some data
aapl = np.array(AAPL['adj_close'])
aapl_dates = np.array(AAPL['date'], dtype=np.datetime64)

In [34]:
window_size = 30
window = np.ones(window_size)/float(window_size)
aapl_avg = np.convolve(aapl,window, 'same')

In [35]:
# output to static HTML file
output_file("stocks.html", title="stocks.py example")
  • setting the plot_width and plot_height arguments to figure()

In [36]:
# create a new plot with a datetime axis type
p = figure(plot_width=800, plot_height=350, x_axis_type="datetime")

In [37]:
# add renderers
p.circle(aapl_dates, aapl, size=4, color='darkgrey', alpha=0.2, legend='close')
p.line(aapl_dates, aapl_avg, color='navy', legend='avg')


Out[37]:
GlyphRenderer(
id = '1816', …)
  • customizing plots and other objects by assigning values to their attributes
  • accessing guides and annotations with convenience Figure attributes: legend, grid, xgrid, ygrid, axis, xaxis, yaxis

In [38]:
# NEW: customize by setting attributes
p.title.text = "AAPL One-Month Average"
p.legend.location = "top_left"
p.grid.grid_line_alpha = 0
p.xaxis.axis_label = 'Date'
p.yaxis.axis_label = 'Price'
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1

In [39]:
# show the results
show(p)

Bokeh Application Server

Bokeh server - optional server component. Affords

  • UI widgets and plot selections driving computations and plot updates
  • Intelligent server-side downsampling of large datasets.
  • Streaming data automatically updating plots
  • Sophisticated glyph re-writing and transformations for "Big Data".
  • Plot and dashboard publishing for wider audiences

More information to write Bokeh server plots and apps, consult Running a Bokeh server


In [ ]: