This docs on this page refers to a PREVIOUS VERSION. For the latest stable release, go to https://docs.bokeh.org/

Archived docs for versions <= 1.0.4 have had to be modified from their original published configuration, and may be missing some features (e.g. source listing)

All users are encourage to update to version 1.1 or later, as soon as they are able.

Bokeh Docs

Plotting with Basic Glyphs

Creating Figures

Note that Bokeh plots created using the bokeh.plotting interface come with a default set of tools, and default visual styles. See Styling Visual Attributes for information about how to customize the visual style of plots, and Configuring Plot Tools for information about changing or specifying tools.

Scatter Markers

To scatter circle markers on a plot, use the circle() method of Figure:

from bokeh.plotting import figure, output_file, show

# output to static HTML file
output_file("line.html")

p = figure(plot_width=400, plot_height=400)

# add a circle renderer with a size, color, and alpha
p.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)

# show the results
show(p)

          Similarly, to scatter square markers, use the square() method of Figure:

          from bokeh.plotting import figure, output_file, show
          
          # output to static HTML file
          output_file("square.html")
          
          p = figure(plot_width=400, plot_height=400)
          
          # add a square renderer with a size, color, and alpha
          p.square([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="olive", alpha=0.5)
          
          # show the results
          show(p)
          

                  There are lots of marker types available in Bokeh, you can see details and example plots for all of them by clicking on entries in the list below:

                  All the markers have the same set of properties: x, y, size (in screen units), and angle (radians by default). Additionally, circle() has a radius property that can be used to specify data-space units.

                  Line Glyphs

                  Single Lines

                  Below is an example that shows how to generate a single line glyph from one dimensional sequences of x and y points using the line() glyph method:

                  from bokeh.plotting import figure, output_file, show
                  
                  output_file("line.html")
                  
                  p = figure(plot_width=400, plot_height=400)
                  
                  # add a line renderer
                  p.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=2)
                  
                  show(p)
                  

                          Multiple Lines

                          Sometimes it is useful to plot multiple lines all at once. This can be accomplished with the multi_line() glyph method:

                          from bokeh.plotting import figure, output_file, show
                          
                          output_file("patch.html")
                          
                          p = figure(plot_width=400, plot_height=400)
                          
                          p.multi_line([[1, 3, 2], [3, 4, 6, 6]], [[2, 1, 4], [4, 7, 8, 5]],
                                       color=["firebrick", "navy"], alpha=[0.8, 0.3], line_width=4)
                          
                          show(p)
                          

                                  Note

                                  This glyph is unlike most other glyphs. Instead of accepting a one dimensional list or array of scalar values, it accepts a “list of lists”.

                                  Missing Points

                                  NaN values can be passed to line() and multi_line() glyphs. In this case, you end up with single logical line objects, that have multiple disjoint components when rendered:

                                  from bokeh.plotting import figure, output_file, show
                                  
                                  output_file("line.html")
                                  
                                  p = figure(plot_width=400, plot_height=400)
                                  
                                  # add a line renderer with a NaN
                                  nan = float('nan')
                                  p.line([1, 2, 3, nan, 4, 5], [6, 7, 2, 4, 4, 5], line_width=2)
                                  
                                  show(p)
                                  

                                          Patch Glyphs

                                          Single Patches

                                          Below is an example that shows how to generate a single polygonal patch glyph from one dimensional sequences of x and y points using the patch() glyph method:

                                          from bokeh.plotting import figure, output_file, show
                                          
                                          output_file("patch.html")
                                          
                                          p = figure(plot_width=400, plot_height=400)
                                          
                                          # add a patch renderer with an alpha an line width
                                          p.patch([1, 2, 3, 4, 5], [6, 7, 8, 7, 3], alpha=0.5, line_width=2)
                                          
                                          show(p)
                                          

                                                  Multiple Patches

                                                  Sometimes it is useful to plot multiple lines all at once. This can be accomplished with the patches() glyph method:

                                                  from bokeh.plotting import figure, output_file, show
                                                  
                                                  output_file("patch.html")
                                                  
                                                  p = figure(plot_width=400, plot_height=400)
                                                  
                                                  p.patches([[1, 3, 2], [3, 4, 6, 6]], [[2, 1, 4], [4, 7, 8, 5]],
                                                            color=["firebrick", "navy"], alpha=[0.8, 0.3], line_width=2)
                                                  
                                                  show(p)
                                                  

                                                          Note

                                                          This glyph is unlike most other glyphs. Instead of accepting a one dimensional list or array of scalar values, it accepts a “list of lists”.

                                                          Missing Points

                                                          Just as with line() and multi_line(), NaN values can be passed to patch() and patches() glyphs. In this case, you end up with single logical patch objects, that have multiple disjoint components when rendered:

                                                          from bokeh.plotting import figure, output_file, show
                                                          
                                                          output_file("patch.html")
                                                          
                                                          p = figure(plot_width=400, plot_height=400)
                                                          
                                                          # add a patch renderer with a NaN value
                                                          nan = float('nan')
                                                          p.patch([1, 2, 3, nan, 4, 5, 6], [6, 7, 5, nan, 7, 3, 6], alpha=0.5, line_width=2)
                                                          
                                                          show(p)
                                                          

                                                                  Warning

                                                                  Hit testing on patch objects with NaN values is not currently supported.

                                                                  Rectangles, Ovals and Ellipses

                                                                  To draw axis aligned rectangles (“quads”), use the quad() glyph function, which accepts left, right, top, and bottom values to specify positions:

                                                                  from bokeh.plotting import figure, show, output_file
                                                                  
                                                                  output_file('rectangles.html')
                                                                  
                                                                  p = figure(width=400, height=400)
                                                                  p.quad(top=[2, 3, 4], bottom=[1, 2, 3], left=[1, 2, 3],
                                                                         right=[1.2, 2.5, 3.7], color="#B3DE69")
                                                                  
                                                                  show(p)
                                                                  

                                                                          To draw arbitrary rectangles by specifying a center point, a width, height, and angle, use the rect() glyph function:

                                                                          from math import pi
                                                                          from bokeh.plotting import figure, show, output_file
                                                                          
                                                                          output_file('rectangles_rotated.html')
                                                                          
                                                                          p = figure(width=400, height=400)
                                                                          p.rect(x=[1, 2, 3], y=[1, 2, 3], width=0.2, height=40, color="#CAB2D6",
                                                                                 angle=pi/3, height_units="screen")
                                                                          
                                                                          show(p)
                                                                          

                                                                                  The oval() glyph method accepts the same properties as rect(), but renders oval shapes:

                                                                                  from math import pi
                                                                                  from bokeh.plotting import figure, show, output_file
                                                                                  
                                                                                  output_file('ovals.html')
                                                                                  
                                                                                  p = figure(width=400, height=400)
                                                                                  p.oval(x=[1, 2, 3], y=[1, 2, 3], width=0.2, height=40, color="#CAB2D6",
                                                                                         angle=pi/3, height_units="screen")
                                                                                  
                                                                                  show(p)
                                                                                  

                                                                                          The ellipse() glyph accepts the same properties as oval() and rect() but renders ellipse shapes, which are different from oval ones. In particular, the same value for width and height will render a circle using the ellipse() glyph but not the oval() one:

                                                                                          from math import pi
                                                                                          from bokeh.plotting import figure, show, output_file
                                                                                          
                                                                                          output_file('ellipses.html')
                                                                                          
                                                                                          p = figure(width=400, height=400)
                                                                                          p.ellipse(x=[1, 2, 3], y=[1, 2, 3], width=[0.2, 0.3, 0.1], height=0.3,
                                                                                                    angle=pi/3, color="#CAB2D6")
                                                                                          
                                                                                          show(p)
                                                                                          

                                                                                                  Images

                                                                                                  You can display images on Bokeh plots using the image(), image_rgba(), and image_url() glyph methods.

                                                                                                  The first example here shows how to display images in Bokeh plots from raw RGBA data using image_rgba():

                                                                                                  Note

                                                                                                  This example depends on the open source NumPy library in order to more easily generate an array of RGBA data.

                                                                                                  from __future__ import division
                                                                                                  
                                                                                                  import numpy as np
                                                                                                  
                                                                                                  from bokeh.plotting import figure, output_file, show
                                                                                                  
                                                                                                  # create an array of RGBA data
                                                                                                  N = 20
                                                                                                  img = np.empty((N, N), dtype=np.uint32)
                                                                                                  view = img.view(dtype=np.uint8).reshape((N, N, 4))
                                                                                                  for i in range(N):
                                                                                                      for j in range(N):
                                                                                                          view[i, j, 0] = int(255 * i / N)
                                                                                                          view[i, j, 1] = 158
                                                                                                          view[i, j, 2] = int(255 * j / N)
                                                                                                          view[i, j, 3] = 255
                                                                                                  
                                                                                                  output_file("image_rgba.html")
                                                                                                  
                                                                                                  p = figure(plot_width=400, plot_height=400, x_range=(0, 10), y_range=(0, 10))
                                                                                                  
                                                                                                  p.image_rgba(image=[img], x=[0], y=[0], dw=[10], dh=[10])
                                                                                                  
                                                                                                  show(p)
                                                                                                  

                                                                                                          Segments and Rays

                                                                                                          Sometimes it is useful to be able to draw many individual line segments at once. Bokeh provides the segment() and ray() glyph methods to render these.

                                                                                                          The segment() function accepts start points x0, y0 and end points x1 and y1 and renders segments between these:

                                                                                                          from bokeh.plotting import figure, show
                                                                                                          
                                                                                                          p = figure(width=400, height=400)
                                                                                                          p.segment(x0=[1, 2, 3], y0=[1, 2, 3], x1=[1.2, 2.4, 3.1],
                                                                                                                    y1=[1.2, 2.5, 3.7], color="#F4A582", line_width=3)
                                                                                                          
                                                                                                          show(p)
                                                                                                          

                                                                                                                  The ray() function accepts start points x, y with a length (in screen units) and an angle. The default angle_units are "rad" but can also be changed to "deg". To have an “infinite” ray, that always extends to the edge of the plot, specify 0 for the length:

                                                                                                                  from bokeh.plotting import figure, show
                                                                                                                  
                                                                                                                  p = figure(width=400, height=400)
                                                                                                                  p.ray(x=[1, 2, 3], y=[1, 2, 3], length=45, angle=[30, 45, 60],
                                                                                                                        angle_units="deg", color="#FB8072", line_width=2)
                                                                                                                  
                                                                                                                  show(p)
                                                                                                                  

                                                                                                                          Wedges and Arcs

                                                                                                                          To draw a simple line arc, Bokeh provides the arc() glyph method, which accepts radius, start_angle, and end_angle to determine position. Additionally, the direction property determines whether to render clockwise ("clock") or anti-clockwise ("anticlock") between the start and end angles.

                                                                                                                          from bokeh.plotting import figure, show
                                                                                                                          
                                                                                                                          p = figure(width=400, height=400)
                                                                                                                          p.arc(x=[1, 2, 3], y=[1, 2, 3], radius=0.1, start_angle=0.4, end_angle=4.8, color="navy")
                                                                                                                          
                                                                                                                          show(p)
                                                                                                                          

                                                                                                                                  The wedge() glyph method accepts the same properties as arc(), but renders a filled wedge instead:

                                                                                                                                  from bokeh.plotting import figure, show
                                                                                                                                  
                                                                                                                                  p = figure(width=400, height=400)
                                                                                                                                  p.wedge(x=[1, 2, 3], y=[1, 2, 3], radius=0.2, start_angle=0.4, end_angle=4.8,
                                                                                                                                          color="firebrick", alpha=0.6, direction="clock")
                                                                                                                                  
                                                                                                                                  show(p)
                                                                                                                                  

                                                                                                                                          The annular_wedge() glyph method is similar to arc(), but draws a filled area. It accepts a inner_radius and outer_radius instead of just radius:

                                                                                                                                          from bokeh.plotting import figure, show
                                                                                                                                          
                                                                                                                                          p = figure(width=400, height=400)
                                                                                                                                          p.annular_wedge(x=[1, 2, 3], y=[1, 2, 3], inner_radius=0.1, outer_radius=0.25,
                                                                                                                                                          start_angle=0.4, end_angle=4.8, color="green", alpha=0.6)
                                                                                                                                          
                                                                                                                                          show(p)
                                                                                                                                          

                                                                                                                                                  Finally, the annulus() glyph methods, which accepts inner_radius and outer_radius, can be used to draw filled rings:

                                                                                                                                                  from bokeh.plotting import figure, show
                                                                                                                                                  
                                                                                                                                                  p = figure(width=400, height=400)
                                                                                                                                                  p.annulus(x=[1, 2, 3], y=[1, 2, 3], inner_radius=0.1, outer_radius=0.25,
                                                                                                                                                            color="orange", alpha=0.6)
                                                                                                                                                  
                                                                                                                                                  show(p)
                                                                                                                                                  

                                                                                                                                                          Specialized Curves

                                                                                                                                                          Bokeh also provides quadratic() and bezier() glyph methods for drawing parameterized quadratic and cubic curves. These are somewhat uncommon; please refer to the reference documentation for details.

                                                                                                                                                          Combining Multiple Glyphs

                                                                                                                                                          Combining multiple glyphs on a single plot is a matter of calling more than one glyph method on a single Figure:

                                                                                                                                                          from bokeh.plotting import figure, output_file, show
                                                                                                                                                          
                                                                                                                                                          x = [1, 2, 3, 4, 5]
                                                                                                                                                          y = [6, 7, 8, 7, 3]
                                                                                                                                                          
                                                                                                                                                          output_file("multiple.html")
                                                                                                                                                          
                                                                                                                                                          p = figure(plot_width=400, plot_height=400)
                                                                                                                                                          
                                                                                                                                                          # add both a line and circles on the same plot
                                                                                                                                                          p.line(x, y, line_width=2)
                                                                                                                                                          p.circle(x, y, fill_color="white", size=8)
                                                                                                                                                          
                                                                                                                                                          show(p)
                                                                                                                                                          

                                                                                                                                                                  This principle holds in general for all the glyph methods in bokeh.plotting. Any number of glyphs may be added to a Bokeh plot.

                                                                                                                                                                  Setting Ranges

                                                                                                                                                                  By default, Bokeh will attempt to automatically set the data bounds of plots to fit snugly around the data. Sometimes you may need to set a plot’s range explicitly. This can be accomplished by setting the x_range or y_range properties using a Range1d object that gives the start and end points of the range you want:

                                                                                                                                                                  p.x_range = Range1d(0, 100)
                                                                                                                                                                  

                                                                                                                                                                  As a convenience, the figure() function can also accept tuples of (start, end) as values for the x_range or y_range parameters. Below is a an example that shows both methods of setting the range:

                                                                                                                                                                  from bokeh.plotting import figure, output_file, show
                                                                                                                                                                  from bokeh.models import Range1d
                                                                                                                                                                  
                                                                                                                                                                  output_file("title.html")
                                                                                                                                                                  
                                                                                                                                                                  # create a new plot with a range set with a tuple
                                                                                                                                                                  p = figure(plot_width=400, plot_height=400, x_range=(0, 20))
                                                                                                                                                                  
                                                                                                                                                                  # set a range using a Range1d
                                                                                                                                                                  p.y_range = Range1d(0, 15)
                                                                                                                                                                  
                                                                                                                                                                  p.circle([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=10)
                                                                                                                                                                  
                                                                                                                                                                  show(p)
                                                                                                                                                                  

                                                                                                                                                                          Ranges can also accept a min and max property that allow you to specify the edges of the plot that you do not want the user to be able to pan/zoom beyond.

                                                                                                                                                                          Specifying Axis Types

                                                                                                                                                                          All the examples above use the default linear axis. This axis is suitable for many plots that need to show numerical data on a linear scale. In other cases you may have categorical data, or need to display numerical data on a datetime or log scale. This section shows how to specify the axis type when using bokeh.plotting interface.

                                                                                                                                                                          Categorical Axes

                                                                                                                                                                          from bokeh.plotting import figure, output_file, show
                                                                                                                                                                          
                                                                                                                                                                          factors = ["a", "b", "c", "d", "e", "f", "g", "h"]
                                                                                                                                                                          x = [50, 40, 65, 10, 25, 37, 80, 60]
                                                                                                                                                                          
                                                                                                                                                                          output_file("categorical.html")
                                                                                                                                                                          
                                                                                                                                                                          p = figure(y_range=factors)
                                                                                                                                                                          
                                                                                                                                                                          p.circle(x, factors, size=15, fill_color="orange", line_color="green", line_width=3)
                                                                                                                                                                          
                                                                                                                                                                          show(p)
                                                                                                                                                                          

                                                                                                                                                                                  Datetime Axes

                                                                                                                                                                                  When dealing with timeseries data, or any data that involves dates or times, it is desirable to have an axis that can display labels that are appropriate to different date and time scales.

                                                                                                                                                                                  Note

                                                                                                                                                                                  This example requires a network connection, and depends on the open source Pandas library in order to more easily present realistic timeseries data.

                                                                                                                                                                                  We have seen how to use the figure() function to create plots using the bokeh.plotting interface. This function accepts x_axis_type and y_axis_type as arguments. To specify a datetime axis, pass "datetime" for the value of either of these parameters.

                                                                                                                                                                                  import pandas as pd
                                                                                                                                                                                  from bokeh.plotting import figure, output_file, show
                                                                                                                                                                                  
                                                                                                                                                                                  AAPL = pd.read_csv(
                                                                                                                                                                                          "http://ichart.yahoo.com/table.csv?s=AAPL&a=0&b=1&c=2000&d=0&e=1&f=2010",
                                                                                                                                                                                          parse_dates=['Date']
                                                                                                                                                                                      )
                                                                                                                                                                                  
                                                                                                                                                                                  output_file("datetime.html")
                                                                                                                                                                                  
                                                                                                                                                                                  # create a new plot with a datetime axis type
                                                                                                                                                                                  p = figure(width=800, height=250, x_axis_type="datetime")
                                                                                                                                                                                  
                                                                                                                                                                                  p.line(AAPL['Date'], AAPL['Close'], color='navy', alpha=0.5)
                                                                                                                                                                                  
                                                                                                                                                                                  show(p)
                                                                                                                                                                                  

                                                                                                                                                                                          Note

                                                                                                                                                                                          Future versions of Bokeh will attempt to auto-detect situations when datetime axes are appropriate, and add them automatically by default.

                                                                                                                                                                                          Log Scale Axes

                                                                                                                                                                                          When dealing with data that grows quick (e.g., exponentially), it is often desired to plot one axis on a log scale. Another use-scenario involves fitting data to a power law, in which case is it desired to plot with both axes on a log scale.

                                                                                                                                                                                          As we saw above, the figure() function accepts x_axis_type and y_axis_type as arguments. To specify a log axis, pass "log" for the value of either of these parameters.

                                                                                                                                                                                          from bokeh.plotting import figure, output_file, show
                                                                                                                                                                                          
                                                                                                                                                                                          x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
                                                                                                                                                                                          y = [10**xx for xx in x]
                                                                                                                                                                                          
                                                                                                                                                                                          output_file("log.html")
                                                                                                                                                                                          
                                                                                                                                                                                          # create a new plot with a log axis type
                                                                                                                                                                                          p = figure(plot_width=400, plot_height=400,
                                                                                                                                                                                                     y_axis_type="log", y_range=(10**-1, 10**4))
                                                                                                                                                                                          
                                                                                                                                                                                          p.line(x, y, line_width=2)
                                                                                                                                                                                          p.circle(x, y, fill_color="white", size=8)
                                                                                                                                                                                          
                                                                                                                                                                                          show(p)
                                                                                                                                                                                          

                                                                                                                                                                                                  Twin Axes

                                                                                                                                                                                                  It is possible to add multiple axes representing different ranges to a single plot. To do this, configure the plot with “extra” named ranges in the extra_x_range and extra_y_range properties. Then these named ranges can be referred to when adding new glyph methods, and also to add new axes objects using the add_layout method on Plot. An example is given below:

                                                                                                                                                                                                  from numpy import pi, arange, sin, linspace
                                                                                                                                                                                                  
                                                                                                                                                                                                  from bokeh.plotting import output_file, figure, show
                                                                                                                                                                                                  from bokeh.models import LinearAxis, Range1d
                                                                                                                                                                                                  
                                                                                                                                                                                                  x = arange(-2*pi, 2*pi, 0.1)
                                                                                                                                                                                                  y = sin(x)
                                                                                                                                                                                                  y2 = linspace(0, 100, len(y))
                                                                                                                                                                                                  
                                                                                                                                                                                                  output_file("twin_axis.html")
                                                                                                                                                                                                  
                                                                                                                                                                                                  p = figure(x_range=(-6.5, 6.5), y_range=(-1.1, 1.1))
                                                                                                                                                                                                  
                                                                                                                                                                                                  p.circle(x, y, color="red")
                                                                                                                                                                                                  
                                                                                                                                                                                                  p.extra_y_ranges = {"foo": Range1d(start=0, end=100)}
                                                                                                                                                                                                  p.circle(x, y2, color="blue", y_range_name="foo")
                                                                                                                                                                                                  p.add_layout(LinearAxis(y_range_name="foo"), 'left')
                                                                                                                                                                                                  
                                                                                                                                                                                                  show(p)
                                                                                                                                                                                                  

                                                                                                                                                                                                          Adding Annotations

                                                                                                                                                                                                          Bokeh includes several different types of annotations to allow users to add supplemental information to their visualizations.

                                                                                                                                                                                                          Titles

                                                                                                                                                                                                          Title annotations allow descriptive text to be rendered around the edges of a plot.

                                                                                                                                                                                                          When using bokeh.plotting or bokeh.Charts, the quickest way to add a basic title is to pass the text as the title parameter to Figure or any Chart function:

                                                                                                                                                                                                          from bokeh.plotting import figure, show, output_file
                                                                                                                                                                                                          
                                                                                                                                                                                                          p = figure(title="Basic Title", plot_width=300, plot_height=300)
                                                                                                                                                                                                          p.circle([1,2], [3,4])
                                                                                                                                                                                                          
                                                                                                                                                                                                          output_file("title.html")
                                                                                                                                                                                                          
                                                                                                                                                                                                          show(p)
                                                                                                                                                                                                          

                                                                                                                                                                                                                  The default title is normally on the top of a plot, aligned to the left. But which side of the plot the default title appears on can be controlled by the title_location parameter:

                                                                                                                                                                                                                  from bokeh.plotting import figure, show, output_file
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  p = figure(title="Left Title", title_location="left",
                                                                                                                                                                                                                             plot_width=300, plot_height=300)
                                                                                                                                                                                                                  p.circle([1,2], [3,4])
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  output_file("title.html")
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  show(p)
                                                                                                                                                                                                                  

                                                                                                                                                                                                                          The default Title is accessible through the Plot.title property. Visual properties for font, border, background, and others can be set directly on .title. Here is an example that sets font and background properties as well as the title text and title alignment using .title:

                                                                                                                                                                                                                          from bokeh.plotting import figure, show, output_file
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          p = figure(plot_width=300, plot_height=300)
                                                                                                                                                                                                                          p.circle([1,2], [3,4])
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          # configure visual properties on a plot's title attribute
                                                                                                                                                                                                                          p.title.text = "Title With Options"
                                                                                                                                                                                                                          p.title.align = "right"
                                                                                                                                                                                                                          p.title.text_color = "orange"
                                                                                                                                                                                                                          p.title.text_font_size = "25px"
                                                                                                                                                                                                                          p.title.background_fill_color = "#aaaaee"
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          output_file("title.html")
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          show(p)
                                                                                                                                                                                                                          

                                                                                                                                                                                                                                  Note that the alignment is measured along the direction of text. For example for titles on the left side of a plot “left” will be in the lower corner.

                                                                                                                                                                                                                                  In addition to the default title, it is possible to create and add additional Title objects to plots using the add_layout method of Plots:

                                                                                                                                                                                                                                  from bokeh.models import Title
                                                                                                                                                                                                                                  from bokeh.plotting import figure, show, output_file
                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                  p = figure(title="Left Title", title_location="left",
                                                                                                                                                                                                                                             plot_width=300, plot_height=300)
                                                                                                                                                                                                                                  p.circle([1,2], [3,4])
                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                  # add extra titles with add_layout(...)
                                                                                                                                                                                                                                  p.add_layout(Title(text="Bottom Centered Title", align="center"), "below")
                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                  output_file("title.html")
                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                  show(p)
                                                                                                                                                                                                                                  

                                                                                                                                                                                                                                          If a title and a sticky toolbar are set to the same side, they will occupy the same space:

                                                                                                                                                                                                                                          from bokeh.plotting import figure, show, output_file
                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                          p = figure(title="Top Title with Toolbar", toolbar_location="above",
                                                                                                                                                                                                                                                     plot_width=600, plot_height=300)
                                                                                                                                                                                                                                          p.circle([1,2], [3,4])
                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                          output_file("title.html")
                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                          show(p)
                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                  If the plot size is large enough, this can result in a more compact plot. However if the plot size is not large enough, the title and toolbar may visually overlap in way that is not desirable.

                                                                                                                                                                                                                                                  Legends

                                                                                                                                                                                                                                                  It is possible to create Legend annotations easily by specifying a legend argument to the glyph methods, when creating a plot.

                                                                                                                                                                                                                                                  Note

                                                                                                                                                                                                                                                  This example depends on the open source NumPy library in order to more easily generate better data suitable for demonstrating legends.

                                                                                                                                                                                                                                                  import numpy as np
                                                                                                                                                                                                                                                  from bokeh.plotting import output_file, show, figure
                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                  x = np.linspace(0, 4*np.pi, 100)
                                                                                                                                                                                                                                                  y = np.sin(x)
                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                  output_file("legend.html")
                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                  p = figure()
                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                  p.circle(x, y, legend="sin(x)")
                                                                                                                                                                                                                                                  p.line(x, y, legend="sin(x)")
                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                  p.line(x, 2*y, legend="2*sin(x)",
                                                                                                                                                                                                                                                         line_dash=[4, 4], line_color="orange", line_width=2)
                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                  p.square(x, 3*y, legend="3*sin(x)", fill_color=None, line_color="green")
                                                                                                                                                                                                                                                  p.line(x, 3*y, legend="3*sin(x)", line_color="green")
                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                  show(p)
                                                                                                                                                                                                                                                  

                                                                                                                                                                                                                                                          Arrows

                                                                                                                                                                                                                                                          Arrow annotations can be used to connect glyphs and label annotations or to simply highlight plot regions. Arrows are compound annotations, meaning that their``start`` and end attributes are themselves other ArrowHead annotations. By default, the Arrow annotation is one-sided with the end set as an OpenHead-type arrow head (an open-backed wedge style) and the start property set to None. Double-sided arrows can be created by setting both the start and end properties as appropriate ArrowHead subclass instances.

                                                                                                                                                                                                                                                          Arrows have standard line properties to set the color and appearance of the arrow shaft:

                                                                                                                                                                                                                                                          my_arrow.line_color = "blue"
                                                                                                                                                                                                                                                          my_arrow.line_alpha = 0.6
                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                          Arrows may also be configured to refer to additional non-default x- or y-ranges with the x_range and y_range properties, in the same way as Twin Axes.

                                                                                                                                                                                                                                                          Additionally any arrow head objects in start or end have a size property to control how big the arrow head is, as well as both line and fill properties. The line properties control the outline of the arrow head, and the fill properties control the interior of the arrow head (if applicable).

                                                                                                                                                                                                                                                          from bokeh.plotting import figure, output_file, show
                                                                                                                                                                                                                                                          from bokeh.models import Arrow, OpenHead, NormalHead, VeeHead
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          output_file("arrow.html", title="arrow.py example")
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p = figure(plot_width=600, plot_height=600)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.circle(x=[0, 1, 0.5], y=[0, 0, 0.7], radius=0.1,
                                                                                                                                                                                                                                                                   color=["navy", "yellow", "red"], fill_alpha=0.1)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.add_layout(Arrow(end=OpenHead(line_color="firebrick", line_width=4),
                                                                                                                                                                                                                                                                             x_start=0, y_start=0, x_end=1, y_end=0))
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.add_layout(Arrow(end=NormalHead(fill_color="orange"),
                                                                                                                                                                                                                                                                             x_start=1, y_start=0, x_end=0.5, y_end=0.7))
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.add_layout(Arrow(end=VeeHead(size=35), line_color="red",
                                                                                                                                                                                                                                                                             x_start=0.5, y_start=0.7, x_end=0, y_end=0))
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          show(p)
                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                          Box Annotations

                                                                                                                                                                                                                                                          A BoxAnnotation can be linked to either data or screen coordinates in order to emphasize specific plot regions. By default, box annotation dimensions (e.g. left or top) default will extend the annotation to the edge of the plot area.

                                                                                                                                                                                                                                                          from bokeh.sampledata.glucose import data
                                                                                                                                                                                                                                                          from bokeh.plotting import figure, show, output_file
                                                                                                                                                                                                                                                          from bokeh.models import BoxAnnotation
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          output_file("box_annotation.html", title="box_annotation.py example")
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          TOOLS = "pan,wheel_zoom,box_zoom,reset,save"
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          #reduce data size
                                                                                                                                                                                                                                                          data = data.ix['2010-10-06':'2010-10-13']
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p = figure(x_axis_type="datetime", tools=TOOLS)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.line(data.index.to_series(), data['glucose'], line_color="gray", line_width=1, legend="glucose")
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          low_box = BoxAnnotation(top=80, fill_alpha=0.1, fill_color='red')
                                                                                                                                                                                                                                                          mid_box = BoxAnnotation(bottom=80, top=180, fill_alpha=0.1, fill_color='green')
                                                                                                                                                                                                                                                          high_box = BoxAnnotation(bottom=180, fill_alpha=0.1, fill_color='red')
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.add_layout(low_box)
                                                                                                                                                                                                                                                          p.add_layout(mid_box)
                                                                                                                                                                                                                                                          p.add_layout(high_box)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.title.text = "Glucose Range"
                                                                                                                                                                                                                                                          p.xgrid[0].grid_line_color=None
                                                                                                                                                                                                                                                          p.ygrid[0].grid_line_alpha=0.5
                                                                                                                                                                                                                                                          p.xaxis.axis_label = 'Time'
                                                                                                                                                                                                                                                          p.yaxis.axis_label = 'Value'
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          show(p)
                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                          Labels

                                                                                                                                                                                                                                                          Labels are text elements that can be used to annotate either glyphs or plot regions.

                                                                                                                                                                                                                                                          To create a single text label, use the Label annotation. This annotation is configured with a text property containing the text to be displayed, as well as x and y properties to set the position (in screen or data space units). Additionally a render mode "canvas" or "css" may be specified. Finally, labels have text, border_line, and background_fill properties. These control the visual appearance of the text, as well as the border and background of the bounding box for the text:

                                                                                                                                                                                                                                                          Label(x=70, y=70, x_units='screen' text='Some Stuff', render_mode='css',
                                                                                                                                                                                                                                                                border_line_color='black', border_line_alpha=1.0,
                                                                                                                                                                                                                                                                background_fill_color='white', background_fill_alpha=1.0)
                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                          To create several labels at once, possibly to easily annotate another existing glyph, use the LabelSet annotation, which is configured with a data source, with the text and x and y positions are given as column names. LabelSet objects can also have x_offset and y_offset, which specify a distance in screen space units to offset the label positions from x and y. Finally the render level may be controlled with the level property, to place the label above or underneath other renderers:

                                                                                                                                                                                                                                                          LabelSet(x='x', y='y', text='names', level='glyph',
                                                                                                                                                                                                                                                                   x_offset=5, y_offset=5, source=source)
                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                          The following example illustrates the use of both:

                                                                                                                                                                                                                                                          from bokeh.plotting import figure, show, output_file
                                                                                                                                                                                                                                                          from bokeh.models import ColumnDataSource, Range1d, LabelSet, Label
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          output_file("label.html", title="label.py example")
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          source = ColumnDataSource(data=dict(height=[66, 71, 72, 68, 58, 62],
                                                                                                                                                                                                                                                                                              weight=[165, 189, 220, 141, 260, 174],
                                                                                                                                                                                                                                                                                              names=['Mark', 'Amir', 'Matt', 'Greg',
                                                                                                                                                                                                                                                                                                     'Owen', 'Juan']))
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p = figure(title='Dist. of 10th Grade Students at Lee High',
                                                                                                                                                                                                                                                                     x_range=Range1d(140, 275))
                                                                                                                                                                                                                                                          p.scatter(x='weight', y='height', size=8, source=source)
                                                                                                                                                                                                                                                          p.xaxis[0].axis_label = 'Weight (lbs)'
                                                                                                                                                                                                                                                          p.yaxis[0].axis_label = 'Height (in)'
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          labels = LabelSet(x='weight', y='height', text='names', level='glyph',
                                                                                                                                                                                                                                                                        x_offset=5, y_offset=5, source=source, render_mode='canvas')
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          citation = Label(x=70, y=70, x_units='screen', y_units='screen',
                                                                                                                                                                                                                                                                           text='Collected by Luke C. 2016-04-01', render_mode='css',
                                                                                                                                                                                                                                                                           border_line_color='black', border_line_alpha=1.0,
                                                                                                                                                                                                                                                                           background_fill_color='white', background_fill_alpha=1.0)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.add_layout(labels)
                                                                                                                                                                                                                                                          p.add_layout(citation)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          show(p)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          Collected by Luke C. 2016-04-01

                                                                                                                                                                                                                                                          Spans

                                                                                                                                                                                                                                                          Span annotations are lines that have a single dimension (width or height) and extend to the edge of the plot area.

                                                                                                                                                                                                                                                          from datetime import datetime as dt
                                                                                                                                                                                                                                                          import time
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          from bokeh.sampledata.daylight import daylight_warsaw_2013
                                                                                                                                                                                                                                                          from bokeh.plotting import figure, show, output_file
                                                                                                                                                                                                                                                          from bokeh.models import Span
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          output_file("span.html", title="span.py example")
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p = figure(x_axis_type="datetime", y_axis_type="datetime")
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.line(daylight_warsaw_2013.Date, daylight_warsaw_2013.Sunset,
                                                                                                                                                                                                                                                                 line_dash='solid', line_width=2, legend="Sunset")
                                                                                                                                                                                                                                                          p.line(daylight_warsaw_2013.Date, daylight_warsaw_2013.Sunrise,
                                                                                                                                                                                                                                                                 line_dash='dotted', line_width=2, legend="Sunrise")
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          start_date = time.mktime(dt(2013, 3, 31, 2, 0, 0).timetuple())*1000
                                                                                                                                                                                                                                                          daylight_savings_start = Span(location=start_date,
                                                                                                                                                                                                                                                                                        dimension='height', line_color='green',
                                                                                                                                                                                                                                                                                        line_dash='dashed', line_width=3)
                                                                                                                                                                                                                                                          p.add_layout(daylight_savings_start)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          end_date = time.mktime(dt(2013, 10, 27, 3, 0, 0).timetuple())*1000
                                                                                                                                                                                                                                                          daylight_savings_end = Span(location=end_date,
                                                                                                                                                                                                                                                                                      dimension='height', line_color='red',
                                                                                                                                                                                                                                                                                      line_dash='dashed', line_width=3)
                                                                                                                                                                                                                                                          p.add_layout(daylight_savings_end)
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          p.title.text = "2013 Sunrise and Sunset times in Warsaw"
                                                                                                                                                                                                                                                          p.yaxis.axis_label = 'Time of Day'
                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          show(p)