Matplotlib - Pick Event



In computer programming, a click event refers to an occurrence where a user interacts with an element on the screen, typically by selecting or clicking on it. The event is triggered when the user's input device, such as a mouse or touchscreen, interacts with an object in the graphical representation.

Pick Event in Matplotlib

A pick event in matplotlib occurs when a user selects a location on the canvas close to an artist that has been designated as pickable using Artist.set_picker. This event provides a way to interactively respond to user actions such as clicking on points, rectangles, or text in a plot.

Enabling the Pick Event

Enabling the picking ability of an object can be done by setting the "picker" property of an artist such as Line2D, Text, Patch, Polygon, AxesImage, etc. This property determines whether the artist can trigger a pick event based on user interactions. The options available for the "picker" property are −

  • None − Picking is disabled, which is the default behavior.

  • bool − If True, picking is enabled, and the artist fires a pick event if the mouse event is over it.

  • function − A user-supplied function that determines whether the artist is hit by the mouse event. The function should return hit, props = picker(artist, mouseevent).

After enabling an artist for picking, you need to connect to the figure canvas using the fig.canvas.mpl_connect('pick_event', callback_function) method to receive pick callbacks on mouse press events.

Picking the Points, Rectangles, and Text

It is possible to enable the picking of specific elements like points, rectangles, and text within a plot. This allows users to click on these elements and trigger custom actions.

Example

The following example demonstrates picking points, rectangles, and text in a plot to get the properties of those picked objects.

import matplotlib.pyplot as plt
import numpy as np
from numpy.random import rand

from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
from matplotlib.text import Text

# Fixing random state for reproducibility
np.random.seed(19680801)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(7, 7))
ax1.set_title('click on points, rectangles or text', picker=True)
ax1.set_xlabel('xlabel', picker=True, bbox=dict(facecolor='green'))
ax1.set_ylabel('ylabel', picker=True, bbox=dict(facecolor='red'))
line, = ax1.plot(rand(100), 'o', picker=True, pickradius=5)

# Pick the rectangle.
ax2.bar(range(10), rand(10), picker=True)
# Make the xtick labels pickable.
for label in ax2.get_xticklabels():  
   label.set_picker(True)

def onpick(event):
   if isinstance(event.artist, Line2D):
      thisline = event.artist
      xdata = thisline.get_xdata()
      ydata = thisline.get_ydata()
      ind = event.ind
      print('onpick line:', np.column_stack([xdata[ind], ydata[ind]]))
   elif isinstance(event.artist, Rectangle):
      patch = event.artist
      print('onpick patch:', patch.get_path())
   elif isinstance(event.artist, Text):
      text = event.artist
      print('onpick text:', text.get_text())

fig.canvas.mpl_connect('pick_event', onpick)
plt.show()

Output

On executing the above program you will get the following figure, and click on any points, rectangles, or text to observe the working of this example −

pick_Event_ex1

Following are the properties observed on console window −

onpick line: [[45.          0.63297416]]
onpick text: xlabel
onpick text: ylabel
onpick patch: Path(array([[0., 0.],
   [1., 0.],
   [1., 1.],
   [0., 1.],
   [0., 0.]]), array([ 1,  2,  2,  2, 79], dtype=uint8))
onpick patch: Path(array([[0., 0.],
   [1., 0.],
   [1., 1.],
   [0., 1.],
   [0., 0.]]), array([ 1,  2,  2,  2, 79], dtype=uint8))
onpick line: [[85.          0.93665595]]
onpick text: click on points, rectangles or text
onpick text: 4

Watch the video below to observe how this pick event feature works here.

pick_Event_ex1 gif

Picking on a Scatter Plot

Picking on a scatter plot involves selecting individual points represented by markers. Scatter plots are commonly used to visualize relationships between two variables. Enabling picking on a scatter plot allows users to interactively identify and respond to specific data points.

Example

This example demonstrates picking on a scatter plot where scatter points are backed by a PathCollection.

from numpy.random import rand
import matplotlib.pyplot as plt

# Generate sample data
x, y, c, s = rand(4, 100)

# Define a function to handle pick events on the scatter plot
def onpick3(event):
   ind = event.ind
   print('onpick3 scatter:', ind, x[ind], y[ind])

# Create a Matplotlib figure and axis
fig, ax = plt.subplots(figsize=(7, 4))
ax.set_title('Click on the points')

# Create a scatter plot
ax.scatter(x, y, 100*s, c, picker=True)

# Connect the pick event handler to the figure canvas
fig.canvas.mpl_connect('pick_event', onpick3)
plt.show()

Output

On executing the above program you will get the following figure, and click on any points, rectangles, or text to observe the working of this example −

pick_Event_ex2
onpick scatter: [25] [0.11699828] [0.53441235]
onpick scatter: [27 44] [0.24286321 0.24281114] [0.37273147 0.3410762 ]
onpick scatter: [86] [0.40636809] [0.44143683]
onpick scatter: [60] [0.38819555] [0.47496597]
onpick scatter: [51] [0.63094438] [0.57754482]
onpick scatter: [71] [0.27925334] [0.01716168]
onpick scatter: [72 94] [0.859042   0.86511669] [0.19949375 0.16885001]
onpick scatter: [37] [0.95150989] [0.11653306]

Watch the video below to observe how this pick event feature works here.

pick_Event_ex2 gif

Images Picking

Images that are plotted using Axes.imshow can also be made pickable.

Example

In this example, picking is demonstrated on images plotted using Axes.imshow() method.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.image import AxesImage

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

# Display the images
ax.imshow(np.random.rand(10, 5), extent=(1, 2, 1, 2), picker=True)
ax.imshow(np.random.rand(5, 10), extent=(3, 4, 1, 2), picker=True)
ax.imshow(np.random.rand(20, 25), extent=(1, 2, 3, 4), picker=True)
ax.imshow(np.random.rand(30, 12), extent=(3, 4, 3, 4), picker=True)
ax.set(xlim=(0, 5), ylim=(0, 5))

# Define a function to handle pick events
def onpick(event):
   artist = event.artist
   if isinstance(artist, AxesImage):
      im = artist
      A = im.get_array()
      print('onpick image', A.shape)

# Connect the pick event handler to the figure canvas
fig.canvas.mpl_connect('pick_event', onpick)

plt.show()

Output

On executing the above program you will get the following figure, and click on any points, rectangles, or text to observe the working of this example −

pick_Event_ex3
onpick image (20, 25)
onpick image (30, 12)
onpick image (10, 5)
onpick image (5, 10)
onpick image (5, 10)

Watch the video below to observe how this pick event feature works here.

pick_Event_ex3 gif

Legend Picking

Matplotlib allows picking on legend items, providing a way to interact with the legend elements in a plot. Users can click on legend entries to toggle the visibility of corresponding plot elements.

Example

Here is an example demonstrating how to enable legend picking.

import numpy as np
import matplotlib.pyplot as plt

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

# Create a Matplotlib figure and axis
fig, ax = plt.subplots(figsize=(7, 4))
ax.set_title('Click on legend line to toggle line on/off')

# Plot two lines and create a legend
line1, = ax.plot(x, y1, label='Sin(x)')
line2, = ax.plot(x, y2, label='Cos(x)')
legend = ax.legend(fancybox=True, shadow=True)

lines = [line1, line2]
map_legend_to_ax = {}

pickradius = 5

# Enable picking on the legend
for legend_line, ax_line in zip(legend.get_lines(), lines):
   legend_line.set_picker(pickradius) 
   map_legend_to_ax[legend_line] = ax_line

# Define a function to handle pick events on the legend
def on_legend_pick(event):
   legend_line = event.artist

   # Do nothing if the source of the event is not a legend line.
   if legend_line not in map_legend_to_ax:
     return

   ax_line = map_legend_to_ax[legend_line]
   visible = not ax_line.get_visible()
   ax_line.set_visible(visible)
   # Change the alpha on the line in the legend, so we can see what lines
   # have been toggled.
   legend_line.set_alpha(1.0 if visible else 0.2)
   fig.canvas.draw()

# Connect the pick event handler to the figure canvas
fig.canvas.mpl_connect('pick_event', on_legend_pick)

# Works even if the legend is draggable.
legend.set_draggable(True)
plt.show()

Output

On executing the above program you will get the following figure, and click on any points, rectangles, or text to observe the working of this example −

pick_Event_ex4

Watch the video below to observe how this pick event feature works here.

pick_Event_ex4 gif
Advertisements