Bokeh is a Python library that makes data visualization and presentation tasks easy for data scientists. It provides powerful tools that offer flexibility, interactivity, and scalability for exploring various data insights. In this Answer, we’ll explore how to add color bars, arrows, and band annotations to a graph.
Click the “Run” button in the widget below to draw a graph without bars, arrows, and band annotation. We’ll use the same graph throughout this Answer to illustrate different types of annotations.
from bokeh.plotting import figure, output_file, show import numpy as np # Output to a static HTML file output_file("output.html") # Generate some sample data x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) # Create a new plot with a title and axis labels myPlot = figure(title="Complex Graph Example", x_axis_label='x', y_axis_label='y') # Add scatter plot myPlot.scatter(x, y1, legend_label="sin(x)", color="blue", size=8, alpha=0.5) myPlot.scatter(x, y2, legend_label="cos(x)", color="red", size=8, alpha=0.5) # Add line plots myPlot.line(x, y1, legend_label="sin(x)", line_color="blue", line_width=2) myPlot.line(x, y2, legend_label="cos(x)", line_color="red", line_width=2) # Show the plot show(myPlot)
Note: You can either view the plot in the "Output" tab or by clicking the URL at "Your app can be found at:".
The above code plots two graphs; the first is the sine
wave, and the second is the cosine
wave. Now, we’ll add annotations to this graph.
The color bar is a great way to show the mapping between the data points and colors. Colors presenting the specific data values make quantitative analysis of the data easy. In the Bokeh library, we have a mappers
model that contains several color bars that can be used according to our needs.
We’ll use the LinearColorMapper
through its helper function linear_cmap
which is used to map continuous values to color palettes. This mapper class has color palettes, themes, and other implementations to customize the color bars. Click the “Run” button in the widget below to draw color bars on the graph.
from bokeh.plotting import figure, output_file, show from bokeh.models import ColorBar from bokeh.transform import linear_cmap from bokeh.util.hex import hexbin import numpy as np # Output to a static HTML file output_file("output.html") # Generate some sample data x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) # Create a new plot with a title and axis labels myPlot = figure(title="Complex Graph Example", x_axis_label='x', y_axis_label='y') # Add scatter plot myPlot.scatter(x, y1, legend_label="sin(x)", color="blue", size=8, alpha=0.5) myPlot.scatter(x, y2, legend_label="cos(x)", color="red", size=8, alpha=0.5) # Add line plots myPlot.line(x, y1, legend_label="sin(x)", line_color="blue", line_width=2) myPlot.line(x, y2, legend_label="cos(x)", line_color="red", line_width=2) # Add a hexbin plot bins = hexbin(x, y1, size=0.1) myPlot.hex_tile(q="q", r="r", size=0.1, line_color=None, source=bins, fill_color=linear_cmap('counts', 'Cividis256', 0, max(bins.counts))) # Add color bar legend color_mapper = linear_cmap(field_name='counts', palette='Cividis256', low=0, high=max(bins.counts)) myPlot.add_layout(ColorBar(color_mapper=color_mapper['transform'], width=8, location=(0, 0)), 'right') # Show the plot show(myPlot)
Let’s have a look at the highlighted lines from the code above:
Lines 2–5: We import the required modules from the Bokeh.
Lines 27–28: We define bins
for the sine
graph and add it to our graph. It creates bins on the data points with the Cividis256
color palette.
Lines 31–32: We use the linear_cmap
function to map data points to the color bar and then add the bar to the plot using the add_layout
function.
Arrow annotation is used to connect data points or to show direction on the graphs. We can have arrows with four types of arrowheads in the Bokeh library. The Arrow
model allows us to customize the arrow lines, colors, and heads according to our choice. Click the “Run” button in the widget below to draw arrows on the graph.
from bokeh.plotting import figure, output_file, show from bokeh.models import Arrow, NormalHead import numpy as np # Output to a static HTML file output_file("output.html") # Generate some sample data x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) # Create a new plot with a title and axis labels myPlot = figure(title="Complex Graph Example", x_axis_label='x', y_axis_label='y') # Add scatter plot myPlot.scatter(x, y1, legend_label="sin(x)", color="blue", size=8, alpha=0.5) myPlot.scatter(x, y2, legend_label="cos(x)", color="red", size=8, alpha=0.5) # Add line plots myPlot.line(x, y1, legend_label="sin(x)", line_color="blue", line_width=1) myPlot.line(x, y2, legend_label="cos(x)", line_color="red", line_width=1) # Add an arrow annotation ah1 = NormalHead(line_width=2, size=10, fill_color="green") ah2 = NormalHead(line_width=2, size=10, fill_color="red") ah3 = NormalHead(line_width=2, size=10, fill_color="blue") arrow_1 = Arrow(end=ah1, x_start=3.2, y_start=0, x_end=4.7, y_end=-1, line_width=4) arrow_2 = Arrow(end=ah2, x_start=4.7, y_start=-1, x_end=6.3, y_end=0, line_width=4) arrow_3 = Arrow(end=ah3, x_start=6.3, y_start=0, x_end=3.2, y_end=0, line_width=4) myPlot.add_layout(arrow_1) myPlot.add_layout(arrow_2) myPlot.add_layout(arrow_3) # Show the plot show(myPlot)
The above code creates a triangle on the sine
wave using three arrows. Let’s see the explanation of the highlighted lines from the above code:
Line 2: We import the Arrow
and NormalHead
models. We have three more arrowheads, VeeHead
, OpenHead
, and TeeHead
available.
Lines 25–27: We define three arrowheads for three arrows. We also specify the head size, line width of the arrowheads, and colors of the arrowheads.
Lines 28–30: We define the arrows using the Arrow method that takes the arrowhead, the starting and ending positions of the arrow, and the line height.
Lines 32–34: We add the arrows to the plot.
A band annotation is a region around the data points that can be used to demonstrate several cases. We can use a band to show the covered area between two lines and mark the saturated area in data distributions. We can highlight the region that could be a part of analytics, and the data points outside the band can be considered outliers.
In the following code widget, we use the Band
model to highlight the region between sine
and cosine
waves. Click the “Run” button in the widget below to draw band annotations on the graph.
from bokeh.plotting import figure, output_file, show from bokeh.models import Band, ColumnDataSource import numpy as np # Output to a static HTML file output_file("output.html") # Generate some sample data x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) # Create a new plot with a title and axis labels myPlot = figure(title="Complex Graph Example", x_axis_label='x', y_axis_label='y') # Add scatter plot myPlot.scatter(x, y1, legend_label="sin(x)", color="blue", size=8, alpha=0.5) myPlot.scatter(x, y2, legend_label="cos(x)", color="red", size=8, alpha=0.5) # Add line plots myPlot.line(x, y1, legend_label="sin(x)", line_color="blue", line_width=2) myPlot.line(x, y2, legend_label="cos(x)", line_color="red", line_width=2) # Convert data to ColumnDataSource source = ColumnDataSource(data=dict(x=x, y1=y1, y2=y2)) # Add a band annotation between sin(x) and cos(x) band = Band(base='x', lower='y1', upper='y2', source=source, level='underlay', fill_alpha=0.1, line_width=1, fill_color="yellow", line_color='red', line_alpha=0.3) myPlot.add_layout(band) # Show the plot show(myPlot)
Let’s see the explanation of the highlighted lines from the code above.
Line 2: We import the Band
and ColumnDataSource
libraries.
Line 25: We convert the dictionary of our data into a CDS object.
Lines 28–29: We use the Band method to define the properties of the band. The base
parameter defines the position of the band on the plane. The lower
and upper
specify the band’s boundaries, and the data to create a band is given into the source
parameter.
Line 30: We add the band to the graph.
In this Answer, we learned to add three types of annotations in the Bokeh charts. We created a sine
and cosine
graph and implemented the color bar, arrow, and band annotations on them.
Free Resources