Matplotlib - Event Handling



In general programming, an event is defined as the change in the state of an object, that occurs when a user interacts with graphical user interface components, triggering a response from the application. Consider actions like clicking a button, moving the mouse, typing on the keyboard, selecting an item from a list, or scrolling a page - each of these activities is an event, describing a change in the state of the source.

Whereas, event handling is the backbone of interactive software applications. Which is the mechanism that controls the response to these events, determining what should occur when a particular event takes place.

Event Handling in Matplotlib

Matplotlib works with various user interface toolkits, including wxPython, Tkinter, Qt, GTK, and MacOSX. To ensure consistent support for interactive features like panning and zooming across different interfaces, Matplotlib uses a GUI-neutral event handling API. This API was initially based on the GTK model, which was the first user interface Matplotlib supported.

Connecting to Events

The main idea behind event handling in Matplotlib is connecting a callback functions to events. A callback function is executed when a specific event, such as a mouse click or key press, occurs. This mechanism enables you to respond to user interactions and implement customized behavior.

If needed, you can disconnect the callback using the connection ID obtained from the mpl_connect method.

fig.canvas.mpl_disconnect(cid)

Example

This example demonstrates a basic implementation that prints the mouse click location and the pressed button on a Matplotlib plot.

import matplotlib.pyplot as plt
import numpy as np

# Generate sample data
x = np.linspace(0, 10, 100)
y = np.sin(x)

# Create a Matplotlib figure and axis
fig, ax = plt.subplots(figsize=(7, 4))

# Plot the data
ax.plot(x, y)

# Define a callback function to handle events
def onclick(event):
   print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
      ('double' if event.dblclick else 'single', event.button,
      event.x, event.y, event.xdata, event.ydata))

# Connect the event handler to the figure canvas
cid = fig.canvas.mpl_connect('button_press_event', onclick)

plt.show()

Output

On executing the above program you will get the following output −

event_handling_ex1
single click: button=1, x=271, y=266, xdata=3.220737, ydata=0.485644
single click: button=1, x=218, y=226, xdata=2.146083, ydata=0.200062
single click: button=3, x=218, y=226, xdata=2.146083, ydata=0.200062
single click: button=1, x=360, y=245, xdata=5.025346, ydata=0.335713

Watch the video below to observe the works of this example.

event_handling_ex1 gif

Common Events in Matplotlib

Matplotlib supports various events, each represented by a specific class −

  • button_press_event − Triggered when a mouse button is pressed.

  • button_release_event − Triggered when a mouse button is released.

  • close_event − Triggered when the figure is closed.

  • draw_event − Triggered when the canvas has been drawn but the screen widget is not updated.

  • key_press_event − Triggered when a key is pressed.

  • key_release_event − Triggered when a key is released.

  • motion_notify_event − Triggered when the mouse moves.

  • pick_event − Triggered when an artist in the canvas is selected.

  • resize_event − Triggered when the figure canvas is resized.

  • scroll_event − Triggered when the mouse scroll wheel is rolled.

  • figure_enter_event − Triggered when the mouse enters a new figure.

  • figure_leave_event − Triggered when the mouse leaves a figure.

  • axes_enter_event − Triggered when the mouse enters a new axes.

  • axes_leave_event − Triggered when the mouse leaves an axes.

By using these events, you can create dynamic and interactive visualizations in matplotlib.

Event Attributes

All Matplotlib events inherit from the matplotlib.backend_bases.Event class, which has attributes like name, canvas, and guiEvent. Common attributes for MouseEvent include x, y, inaxes, xdata, and ydata.

Example

Let's see this simple example where a line segment is generated with each mouse press on the plot.

from matplotlib import pyplot as plt
import numpy as np

# LineBuilder Class
# It creats line segments based on mouse clicks.
class LineBuilder:
   def __init__(self, line):
      self.line = line
      self.xs = list(line.get_xdata())
      self.ys = list(line.get_ydata())
      self.cid = line.figure.canvas.mpl_connect('button_press_event', self)

   def __call__(self, event):
      if event.inaxes != self.line.axes:
         return
      self.xs.append(event.xdata)
      self.ys.append(event.ydata)
      self.line.set_data(self.xs, self.ys)
      self.line.figure.canvas.draw()

# Create a figure and axis
fig, ax = plt.subplots(figsize=(7, 4))

# Set the title
ax.set_title('Click to Build Line Segments')

# empty line
line, = ax.plot([0], [0])  

# Create an instance for LineBuilder class
linebuilder = LineBuilder(line)

# Show the Plot
plt.show()

Output

On executing the above program you will get the following figure click on this figure to observe the working of this example −

Image

Watch the video below to observe working of this example.

event_handling_ex2 GIF

Detecting the Mouse moves

To detect when the mouse enters or leaves a figure or an axes, we can connect to the figure/axes enter/leave events.

Example

Here is another example that demonstrates how to change frame colors when the mouse enters or leaves specific regions of the figure.

import matplotlib.pyplot as plt

def enter_axes(event):
   event.inaxes.patch.set_facecolor('yellow')
   event.canvas.draw()

def leave_axes(event):
   event.inaxes.patch.set_facecolor('white')
   event.canvas.draw()

def enter_figure(event):
   event.canvas.figure.patch.set_facecolor('red')
   event.canvas.draw()

def leave_figure(event):
   event.canvas.figure.patch.set_facecolor('grey')
   event.canvas.draw()

fig, axs = plt.subplots(2, figsize=(7, 4))
fig.suptitle('Mouse Hover Over Figure or Axes to Trigger Events')

fig.canvas.mpl_connect('figure_enter_event', enter_figure)
fig.canvas.mpl_connect('figure_leave_event', leave_figure)
fig.canvas.mpl_connect('axes_enter_event', enter_axes)
fig.canvas.mpl_connect('axes_leave_event', leave_axes)

plt.show()
Output

On executing the above program you will get the following output −

event_handling_ex3

Watch the video below to observe the works of this example.

event_handling_ex3.gif

Example

Here is another example that demonstrates how to show mouse release event coordinates with Matplotlib

from matplotlib import pyplot as plt

plt.rcParams['backend'] = 'TkAgg'
plt.rcParams["figure.figsize"] = [7, 4]
plt.rcParams["figure.autolayout"] = True

# Define a callback function to handle events
def onclick(event):
   print(event.button, event.xdata, event.ydata)

# Create a Matplotlib figure and axis
fig, ax = plt.subplots()

# Plot the data
ax.plot(range(10))

# Connect the event handler to the figure canvas
fig.canvas.mpl_connect('button_release_event', onclick)

# Show the Plot
plt.show()
Output

On executing the above code we will get the following output −

event_handling_ex4

Watch the video below to observe the works of this example.

event_handling_ex4.gif
Advertisements