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.