Lines and curves#

Single lines#

The example below 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, show

p = figure(width=400, height=400)

# add a line renderer
p.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=2)

show(p)

Step lines#

For some kinds of data, discrete steps between data points may work better than linear segments. To produce this type of data representation, use the step() glyph method.

from bokeh.plotting import figure, show

p = figure(width=400, height=400)

# add a steps renderer
p.step([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=2, mode="center")

show(p)

Adjust the mode parameter to draw step levels with the x-coordinates before, after, or in the middle of each step.

Multiple lines#

If you want to draw multiple lines in one go, use the multi_line() glyph method as follows:

from bokeh.plotting import figure, show

p = figure(width=400, 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

Unlike many other glyph methods, multi_line() accepts a list of lists of x and y positions for each line. The multi_line() method also expects a scalar value or a list of scalars for each line for parameters such as color, alpha, and line width. You can similarly use a ColumnDataSource consisting of a list of lists of point coordinates and a list of scalar values of matching length.

Missing points#

You can pass NaN values to line() and multi_line() glyphs. This produces disjointed lines with gaps for NaN values.

from math import nan

from bokeh.plotting import figure, show

p = figure(width=400, height=400)

# add a line renderer with NaN values
p.line([1, 2, 3, nan, 4, 5], [6, 7, 2, 4, 4, 5], line_width=8,
       legend_label="line with NaN", alpha=0.5)

# don't use None as a value for a renderer, because it will be drawn as 0
p.line([1, 2, 3, None, 4, 5], [6, 7, 2, 4, 4, 5], line_width=2,
       legend_label="line with None (BAD)", line_dash="dashed", color="red")

show(p)

Be aware of the usage of NaN as a number, which can be imported from math or numpy. Do not use the native Python None object, because this will be evaluated as 0 in the created figure and therefore drawn. None will not lead to gaps in the line and can have implicit effects on the figure, e.g. the ranges of the figure.

Stacked lines#

You may wish to stack lines with a common index when working with time series of percentages and other similar data. To do so, you can use the vline_stack() and hline_stack() convenience methods.

from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show

source = ColumnDataSource(data=dict(
    x=[1, 2, 3, 4, 5],
    y1=[1, 2, 4, 3, 4],
    y2=[1, 4, 2, 2, 3],
))
p = figure(width=400, height=400)

p.vline_stack(['y1', 'y2'], x='x', source=source)

show(p)

Note

This and other examples in this chapter rely on ColumnDataSource for data structuring. For information on how to work with this data structure, see Data sources.

Combining with markers#

You can combine multiple glyphs on a single plot by calling their methods on a single figure().

from bokeh.plotting import figure, show

x = [1, 2, 3, 4, 5]
y = [6, 7, 8, 7, 3]

p = figure(width=400, height=400)

# add both a line and circles on the same plot
p.line(x, y, line_width=2)
p.scatter(x, y, fill_color="white", size=8)

show(p)

This principle applies to all bokeh.plotting glyph methods. You can add as many glyphs to a Bokeh plot as you want.

Specialized glyphs#

Segments#

To draw multiple individual line segments use the segment() and ray() glyph methods.

The segment() method accepts the starting points x0 and y0 and end points x1 and y1. It renders segments between those points.

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)

Rays#

The ray() method accepts the starting points x and y with a length (in screen units) and an angle. The angle_units parameter defaults to "rad" but you can also set it to "deg" to have the angle measured in degrees instead of radians. To have an “infinite” ray that always extends to the edge of the plot, set length to 0.

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)

Spans#

To draw multiple horizontal or vertical spans (lines of infinite width or height respectively), use the hspan() or vspan() glyph methods. These methods accept either y or x coordinate components respectively. Note that these glyphs can only compute bounds in one axis, thus may require explicit range specification in the orthogonal axis, e.g. if used alone.

from bokeh.io import show
from bokeh.plotting import figure

plot = figure()

plot.hspan(
    y=[0, 5, 15, 33],
    line_width=[1, 2, 3, 4], line_color="red",
)
plot.vspan(
    x=[0, 5, 15, 33],
    line_width=[1, 2, 3, 4], line_color="blue",
)

show(plot)

Arcs#

To draw a simple line arc, use 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)

Parameterized#

To draw parameterized quadratic and cubic curves, use the quadratic() and bezier() glyph methods. For more detail on these curves, see reference documentation.