Home » Tutorial on the Matplotlib SpanSelector in Python

Tutorial on the Matplotlib SpanSelector in Python

Oracle Java Certification
Java SE 11 Programmer I [1Z0-815] Practice Tests
Java SE 11 Programmer II [1Z0-816] Practice Tests
1 Year Subscription
Java SE 11 Developer (Upgrade) [1Z0-817]
Spring Framework Basics Video Course

The SpanSelector widget in Matplotlib provides an easy way to select a range within a plot by clicking and dragging.

This widget is particularly useful for selecting ranges on one of the axes (typically x-axis or y-axis) to zoom into data, highlight specific sections, or analyze specific intervals in time series or other continuous data.

In this tutorial, we’ll cover the basics of creating and using the SpanSelector widget in Matplotlib, along with examples demonstrating different applications, including zooming, data filtering, and interactive analysis.

1. Basic Setup for the SpanSelector

The SpanSelector widget allows you to select a range along a specified axis. It requires defining a callback function that handles the event after a range has been selected.

Basic Structure of SpanSelector

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector

# Sample data for a line plot
x = np.linspace(0, 10, 100)
y = np.sin(x)

# Create a figure and plot
fig, ax = plt.subplots()
ax.plot(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")

# Callback function to handle the selection
def onselect(xmin, xmax):
    print(f"Range selected from {xmin:.2f} to {xmax:.2f}")

# Create the SpanSelector object
span_selector = SpanSelector(ax, onselect, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='red'))

plt.show()

In this example:

  • SpanSelector(ax, onselect, ‘horizontal', useblit=True) creates a horizontal SpanSelector.
  • The onselect callback function is called when a range is selected, printing the minimum and maximum values of the selected range.
  • rectprops=dict(alpha=0.5, facecolor='red') customizes the appearance of the selection rectangle with 50% transparency and red color.

2. Highlighting Selected Range

You can use the SpanSelector to highlight a selected range by shading it or drawing a rectangle over the selection.

# Create figure and plot
fig, ax = plt.subplots()
ax.plot(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")

# Create an empty rectangle to show the selected range
highlight = ax.axvspan(0, 0, color='yellow', alpha=0.3, visible=False)

# Callback function to highlight the selected range
def onselect(xmin, xmax):
    highlight.set_visible(True)
    highlight.set_xy([[xmin, ax.get_ylim()[0]], [xmin, ax.get_ylim()[1]], [xmax, ax.get_ylim()[1]], [xmax, ax.get_ylim()[0]], [xmin, ax.get_ylim()[0]]])
    fig.canvas.draw_idle()

# Create the SpanSelector
span_selector = SpanSelector(ax, onselect, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='blue'))

plt.show()

In this example:

  • The highlight rectangle is initially invisible but becomes visible after the selection.
  • The onselect function updates the rectangle’s coordinates to match the selected range, shading the selected region.

3. Using SpanSelector to Zoom into Selected Range

One of the most common applications of the SpanSelector is zooming into the selected range by setting the x-axis limits based on the selection.

# Create figure and plot
fig, ax = plt.subplots()
ax.plot(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")

# Callback function to zoom into selected range
def onselect(xmin, xmax):
    ax.set_xlim(xmin, xmax)
    plt.draw()

# Create the SpanSelector
span_selector = SpanSelector(ax, onselect, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green'))

plt.show()

In this example:

  • The onselect function updates the x-axis limits to zoom into the selected range.
  • plt.draw() is called to refresh the plot immediately after changing the limits.

4. SpanSelector for Range Filtering

You can use SpanSelector to select a specific range and display only the data within that range, effectively filtering the data shown.

# Create figure and initial plot
fig, ax = plt.subplots()
sc = ax.scatter(x, y, label="Data")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")

# Callback function to filter data within selected range
def onselect(xmin, xmax):
    mask = (x >= xmin) & (x <= xmax)
    sc.set_offsets(np.c_[x[mask], y[mask]])  # Update scatter plot with filtered data
    fig.canvas.draw_idle()

# Create the SpanSelector
span_selector = SpanSelector(ax, onselect, 'horizontal', useblit=True, rectprops=dict(alpha=0.3, facecolor='purple'))

plt.show()

In this example:

  • The onselect function creates a mask to filter x and y values within the selected range and updates the scatter plot accordingly.

5. Adjusting SpanSelector to Select on Y-Axis

The SpanSelector can also be used to select ranges vertically along the y-axis by setting the orientation to ‘vertical'.

# Create figure and plot
fig, ax = plt.subplots()
ax.plot(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")

# Callback function for vertical selection
def onselect(ymin, ymax):
    print(f"Range selected from {ymin:.2f} to {ymax:.2f}")

# Create the SpanSelector for vertical selection
span_selector = SpanSelector(ax, onselect, 'vertical', useblit=True, rectprops=dict(alpha=0.3, facecolor='orange'))

plt.show()

In this example:

  • SpanSelector is set to vertical selection mode by setting ‘vertical' for the third parameter.
  • The callback function onselect now receives ymin and ymax values from the selection.

6. Using SpanSelector to Adjust Plot Limits in Real-Time

You can use SpanSelector to dynamically adjust the plot limits in real-time, allowing users to set the limits interactively.

# Create figure and plot
fig, ax = plt.subplots()
ax.plot(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")

# Callback function to adjust x-axis limits based on selection
def onselect(xmin, xmax):
    ax.set_xlim(xmin, xmax)
    plt.draw()

# SpanSelector for adjusting plot limits
span_selector = SpanSelector(ax, onselect, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='cyan'))

plt.show()

In this example:

  • The onselect function directly updates the plot’s x-axis limits.
  • This interactive zoom effect allows users to focus on specific data ranges.

7. Selecting and Analyzing Time Series Data with SpanSelector

The SpanSelector is very useful for analyzing specific time intervals in time series data. This example uses SpanSelector to calculate and display the mean value within the selected range.

# Sample time series data
time = np.linspace(0, 10, 100)
signal = np.sin(time) + 0.5 * np.random.normal(size=time.shape)

# Create figure and plot time series
fig, ax = plt.subplots()
ax.plot(time, signal, label="Signal")
plt.xlabel("Time")
plt.ylabel("Signal Value")

# Callback function to calculate mean in the selected range
def onselect(tmin, tmax):
    mask = (time >= tmin) & (time <= tmax)
    mean_val = signal[mask].mean()
    ax.set_title(f"Mean Value in Selected Range: {mean_val:.2f}")
    plt.draw()

# SpanSelector for selecting time range
span_selector = SpanSelector(ax, onselect, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='yellow'))

plt.show()

In this example:

  • The onselect function calculates the mean value of the signal within the selected range and displays it as the plot title.
  • This approach is useful for time series analysis, allowing you to compute statistics over selected intervals.

8. SpanSelector with Multiple Axes (Subplots)

If you have multiple subplots, you can use SpanSelector to control multiple axes simultaneously. Here’s an example where the x-axis range is controlled across two subplots.

# Sample data for two subplots
y1 = np.sin(x)
y2 = np.cos(x)

# Create figure with two subplots
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
ax1.plot(x, y1, label="sin(x)")
ax2.plot(x, y2, label="cos(x)")
plt.xlabel("X-axis")

# Callback function to apply range selection across both subplots
def onselect(xmin, xmax):
    ax1.set_xlim(xmin, xmax)
    ax2.set_xlim(xmin, xmax)
    plt.draw()

# SpanSelector for both subplots
span_selector = SpanSelector(ax1, onselect, 'horizontal', useblit=True, rectprops=dict(alpha=0.3, facecolor='lightblue'))

plt.show()

In this example:

  • The onselect function updates the x-axis limits of both subplots simultaneously, keeping them in sync.
  • This approach is useful for exploring specific ranges across multiple views.

9. Dis

abling and Enabling SpanSelector with Keyboard Shortcuts

You can add keyboard controls to enable or disable the SpanSelector, adding flexibility to its use.

# Create figure and plot
fig, ax = plt.subplots()
ax.plot(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")

# Callback function for selection
def onselect(xmin, xmax):
    print(f"Range selected from {xmin:.2f} to {xmax:.2f}")

# Create SpanSelector
span_selector = SpanSelector(ax, onselect, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='gray'))

# Key event function to enable/disable SpanSelector
def on_key(event):
    if event.key == 'e':  # Enable SpanSelector
        span_selector.set_active(True)
        print("SpanSelector enabled")
    elif event.key == 'd':  # Disable SpanSelector
        span_selector.set_active(False)
        print("SpanSelector disabled")

# Connect the key press event to the handler
fig.canvas.mpl_connect('key_press_event', on_key)
plt.show()

In this example:

  • Pressing ‘e' enables the SpanSelector.
  • Pressing ‘d' disables the SpanSelector, allowing you to turn it on or off as needed.

Summary

In this tutorial, we covered several ways to use the SpanSelector widget in Matplotlib to interactively select ranges in your plots:

  1. Basic SpanSelector Setup with a callback function.
  2. Highlighting Selected Range within the plot.
  3. Zooming into Selected Range by adjusting plot limits.
  4. Filtering Data within Selected Range for scatter plots.
  5. Selecting on Y-Axis by setting SpanSelector to vertical mode.
  6. Adjusting Plot Limits in Real-Time for interactive zoom.
  7. Analyzing Time Series Data by calculating statistics within selected intervals.
  8. Controlling Multiple Subplots to select ranges across different axes.
  9. Enabling/Disabling SpanSelector using keyboard shortcuts.

You may also like

Leave a Comment

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More