The Matplotlib Cursor widget allows you to track data points interactively in a plot by providing a visual cursor. This can be helpful for exploring data points in a plot, especially in line plots and scatter plots, by showing crosshair lines or a moving indicator.
Matplotlib provides a Cursor widget in its mpl_toolkits.widgets module, which allows us to add a cursor to a plot. Additionally, other interactive cursors can be implemented by using event handling.
In this tutorial, we’ll cover the basics of adding and customizing the cursor widget in Matplotlib, and explore some interactive examples.
1. Setting Up a Basic Cursor with Cursor
The Cursor widget in Matplotlib is simple to use. It displays a crosshair cursor that follows the mouse movement on the plot.
import matplotlib.pyplot as plt from matplotlib.widgets import Cursor # Create some sample data x = [0, 1, 2, 3, 4, 5] y = [0, 1, 4, 9, 16, 25] # Create a plot fig, ax = plt.subplots() ax.plot(x, y, 'o-', label="y = x^2") # Add a cursor widget cursor = Cursor(ax, useblit=True, color='red', linewidth=1) plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.title("Basic Cursor Example") plt.legend() plt.show()
In this example:
- useblit=True makes the cursor smoother by redrawing only the cursor.
- color and linewidth customize the appearance of the cursor lines.
2. Customizing Cursor Appearance
The cursor's appearance can be adjusted by changing parameters like color, line width, and line style.
# Create a plot with more customized cursor fig, ax = plt.subplots() ax.plot(x, y, 'o-', label="y = x^2") # Customize cursor appearance cursor = Cursor(ax, useblit=True, color='blue', linewidth=2, linestyle='--') plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.title("Customized Cursor Appearance") plt.legend() plt.show()
In this example, the cursor lines are set to a blue color with a dashed line style.
3. Using Snap=True to Snap Cursor to Data Points
When you set snap=True, the cursor will snap to the closest data point, which can be useful when exploring specific values.
# Create a plot with snap-to-point cursor fig, ax = plt.subplots() ax.plot(x, y, 'o-', label="y = x^2") # Enable snapping to data points cursor = Cursor(ax, useblit=True, color='green', linewidth=1, snap=True) plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.title("Cursor with Snap to Data Points") plt.legend() plt.show()
4. Displaying Data Coordinates with Cursor
You can combine the cursor with Matplotlib’s motion_notify_event to display the coordinates of the cursor's current position in real time. This can be achieved by setting up an event listener.
# Create plot fig, ax = plt.subplots() ax.plot(x, y, 'o-', label="y = x^2") # Add a cursor cursor = Cursor(ax, useblit=True, color='purple', linewidth=1) # Function to display data coordinates def on_mouse_move(event): if event.inaxes: ax.set_title(f"Mouse Position: x={event.xdata:.2f}, y={event.ydata:.2f}") fig.canvas.draw_idle() # Connect event to mouse movement fig.canvas.mpl_connect('motion_notify_event', on_mouse_move) plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.legend() plt.show()
In this example, on_mouse_move updates the plot title with the current coordinates of the cursor. The function is triggered every time the mouse moves within the axes.
5. Interactive Data Exploration with Cursor and Click Events
You can enhance the cursor functionality by adding a click event to store and highlight selected data points.
# Create plot fig, ax = plt.subplots() ax.plot(x, y, 'o-', label="y = x^2") highlight, = ax.plot([], [], 'ro', markersize=10, label="Selected Point") # Add a cursor cursor = Cursor(ax, useblit=True, color='orange', linewidth=1) # Click event to store and highlight data points def on_click(event): if event.inaxes: highlight.set_data([event.xdata], [event.ydata]) ax.set_title(f"Selected Point: x={event.xdata:.2f}, y={event.ydata:.2f}") fig.canvas.draw_idle() # Connect click event fig.canvas.mpl_connect('button_press_event', on_click) plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.legend() plt.show()
In this example:
- on_click stores and highlights the selected data point.
- A red marker (highlight) marks the selected point, and the title is updated with the coordinates.
6. Using mplcursors for Easy Tooltips with Cursors
The mplcursors library is an additional package that provides interactive tooltips in Matplotlib. It can be installed with pip install mplcursors.
import mplcursors # Create plot fig, ax = plt.subplots() ax.plot(x, y, 'o-', label="y = x^2") # Add mplcursors tooltips mplcursors.cursor(hover=True) plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.title("Interactive Tooltips with mplcursors") plt.legend() plt.show()
With mplcursors, you get interactive tooltips that display data point coordinates by simply hovering over the points. Setting hover=True enables hover-based tooltips.
7. Creating a Dual-Axis Cursor
You can create a cursor that moves along both x and y axes independently using two crosshairs.
import matplotlib.lines as mlines # Create plot fig, ax = plt.subplots() ax.plot(x, y, 'o-', label="y = x^2") # Add two crosshair lines h_line = mlines.Line2D([], [], color='gray', linestyle='--') v_line = mlines.Line2D([], [], color='gray', linestyle='--') ax.add_line(h_line) ax.add_line(v_line) # Update function for crosshairs def on_mouse_move(event): if event.inaxes: h_line.set_data([ax.get_xlim()[0], ax.get_xlim()[1]], [event.ydata, event.ydata]) v_line.set_data([event.xdata, event.xdata], [ax.get_ylim()[0], ax.get_ylim()[1]]) ax.set_title(f"Mouse Position: x={event.xdata:.2f}, y={event.ydata:.2f}") fig.canvas.draw_idle() # Connect event fig.canvas.mpl_connect('motion_notify_event', on_mouse_move) plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.legend() plt.show()
In this example:
- h_line and v_line are horizontal and vertical lines representing the cursor.
- The on_mouse_move function updates their position as the mouse moves, giving the effect of a crosshair cursor.
8. Advanced Data Exploration with Hover Effect Using mplcursors
With mplcursors, you can create a more advanced data exploration tool where detailed information about each data point appears on hover.
# Sample data x = [1, 2, 3, 4, 5] y = [2, 4, 1, 3, 5] labels = ['Point A', 'Point B', 'Point C', 'Point D', 'Point E'] # Create plot fig, ax = plt.subplots() sc = ax.scatter(x, y) # Add interactive tooltips with labels cursor = mplcursors.cursor(sc, hover=True) cursor.connect("add", lambda sel: sel.annotation.set_text(labels[sel.index])) plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.title("Advanced Tooltips with Labels") plt.show()
In this example, mplcursors is used to display a label for each data point on hover. The label text corresponds to the point index in the labels list, making it easy to identify individual points.
Summary
In this tutorial, we covered several ways to use and customize the cursor widget in Matplotlib:
- Basic cursor setup using Cursor.
- Customizing cursor appearance (color, width, and style).
- Snapping the cursor to data points.
- Displaying data coordinates with mouse movement.
- Selecting and highlighting data points with click events.
- Using mplcursors for hover tooltips.
- Creating a dual-axis cursor with crosshair lines.
- Advanced hover-based exploration with labels.