5 Best Ways to Visualize Multiple Lines Using Bokeh in Python

πŸ’‘ Problem Formulation: When dealing with multiple datasets or time-series data, it is often necessary to visualize these datasets on a single plot for comparison. Using the Bokeh library in Python, one can create interactive and visually appealing plots. The objective is to demonstrate how multiple lines, each representing a different dataset, can be plotted on a single Bokeh figure.

Method 1: Plotting Multiple Lines Individually

Bokeh’s flexibility allows individual addition of lines to a figure using the line() function, enabling customization of each line’s properties such as color, width, and legend. This method provides a streamlined approach to altering the aesthetics and behavior of each dataset’s representation on the plot.

Here’s an example:

from bokeh.plotting import figure, output_file, show

# Prepare the data
x = [1, 2, 3, 4, 5]
y1 = [6, 7, 2, 4, 5]
y2 = [2, 4, 7, 2, 8]

# Output to static HTML file
output_file("lines.html")

# Create a new plot
p = figure(title="Multiple Lines Example", x_axis_label='X', y_axis_label='Y')

# Add multiple lines
p.line(x, y1, legend_label="Line 1", line_width=2, color="blue")
p.line(x, y2, legend_label="Line 2", line_width=2, color="green")

# Show the result
show(p)

The output of this code snippet is an HTML file visualizing a Bokeh plot with two distinct lines representing two separate datasets.

This code snippet creates a Bokeh plot and displays two lines with different colors. By calling the line() function for each dataset (y1 and y2), we ensure they are individually added to the plot with their respective properties.

Method 2: Using Multi-Line for Batch Plotting

This method leverages the multi_line() function, which accepts lists of x and y coordinates, allowing for batch plotting of lines. This can significantly reduce code verbosity and is efficient when plotting lines with shared stylistic properties.

Here’s an example:

from bokeh.plotting import figure, output_file, show

# Prepare the data
xs = [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
ys = [[6, 7, 2, 4, 5], [2, 4, 7, 2, 8]]

# Output to static HTML file
output_file("multi_lines.html")

# Create a new plot
p = figure(title="Multi-Line Example", x_axis_label='X', y_axis_label='Y')

# Add multiple lines in one call
p.multi_line(xs, ys, color=["blue", "green"], line_width=4)

# Show the result
show(p)

The output is a Bokeh plot with lines that have been batch plotted, offering a convenient way to visualize datasets with similar aesthetic requirements.

The code creates a Bokeh plot and uses the multi_line() function to draw all lines in one call, streamlining the plot creation process. This approach is efficient when dealing with multiple datasets that have the same line styles.

Method 3: Combining ColumnDataSource with Line Glyphs

When plotting multiple lines, using a ColumnDataSource can be highly efficient, particularly for sharing data between glyphs or when updating the data source triggers updates in the plot. It provides a central repository for data related to the lines.

Here’s an example:

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

# Prepare the data
source = ColumnDataSource(data=dict(x=[1, 2, 3, 4, 5], y1=[6, 7, 2, 4, 5], y2=[2, 4, 7, 2, 8]))

# Output to static HTML file
output_file("column_data_source.html")

# Create a new plot
p = figure(title="ColumnDataSource Example", x_axis_label='X', y_axis_label='Y')

# Add multiple lines using the same source
p.line('x', 'y1', source=source, legend_label="Line 1", line_width=2, color="blue")
p.line('x', 'y2', source=source, legend_label="Line 2", line_width=2, color="red")

# Show the result
show(p)

The output is a Bokeh plot with multiple lines sharing the same data source, which can be manipulated to dynamically update the plot.

In the provided example, the ColumnDataSource is used to store the data for both lines. This method simplifies the management of the plot’s data and is ideal for interactive plots where the underlying data may change.

Method 4: Adding Lines with For-Loop

Iterating over a dataset with a for-loop and plotting lines individually is practical for datasets that are stored in a structured form, like dictionaries or DataFrames. This method provides versatility in dynamically generating plots based on the data’s structure.

Here’s an example:

from bokeh.plotting import figure, output_file, show

# Prepare the data
data = {'x_values': [1, 2, 3, 4, 5],
        'y_sets': [[6, 7, 2, 4, 5], [2, 4, 7, 2, 8], [5, 7, 3, 2, 6]]}

# Output to static HTML file
output_file("for_loop_lines.html")

# Create a new plot
p = figure(title="For-Loop Lines Example", x_axis_label='X', y_axis_label='Y')

# Adding lines with a for-loop
colors = ['blue', 'green', 'orange']
for y, color in zip(data['y_sets'], colors):
    p.line(data['x_values'], y, line_width=2, color=color)

# Show the result
show(p)

The output is a Bokeh plot with lines added through a for-loop, useful for plots where data might be added incrementally or programmatically.

This example uses a for-loop to iterate over a list of y-values, plotting each as a separate line. This method is powerful for cases where the number of lines or their data may not be known beforehand.

Bonus One-Liner Method 5: Plotting Lines with Pandas Integration

Bokeh seamlessly integrates with Pandas, allowing for the direct plotting of DataFrame columns. Using the from_bokeh() Pandas accessor, multiple lines can be visualized succinctly in just one line of code.

Here’s an example:

import pandas as pd
from bokeh.plotting import output_file, show
from bokeh import plotting

# Prepare the data in a DataFrame
df = pd.DataFrame({
    'x': [1, 2, 3, 4, 5],
    'y1': [6, 7, 2, 4, 5],
    'y2': [2, 4, 7, 2, 8]
})

# Output to static HTML file
output_file("pandas_bokeh.html")

# Use the Pandas integration to plot
p = df.plot_bokeh(kind="line", x='x', y=['y1', 'y2'])

# Show the result
show(p)

The output is a Bokeh plot where each column of the DataFrame that contains y values is visualized as a separate line.

The above code snippet generates a plot directly from a Pandas DataFrame, highlighting the convenience of integrating Bokeh with Pandas data structures.

Summary/Discussion

  • Method 1: Plotting Multiple Lines Individually. Strengths: Fine-grained control over each line. Weaknesses: Can be verbose with many lines.
  • Method 2: Using Multi-Line for Batch Plotting. Strengths: Convenient for many lines with shared styles. Weaknesses: Limited individual customization.
  • Method 3: Combining ColumnDataSource with Line Glyphs. Strengths: Centralized data management and interactive updating. Weaknesses: Potentially more complex setup.
  • Method 4: Adding Lines with For-Loop. Strengths: Dynamic and flexible with data structure. Weaknesses: Can become inefficient with very large datasets.
  • Bonus Method 5: Plotting Lines with Pandas Integration. Strengths: Extremely concise for DataFrame objects. Weaknesses: Relies on the structure of the DataFrame.