选择事件演示#

您可以通过设置绘图对象(例如 Matplotlib Line2D、Text、Patch、Polygon、AxesImage 等)的“picker”属性来启用选择功能。

picker 属性有多种含义:

  • None - 此绘图对象禁用选择(默认)

  • bool - 如果为True,则选择将启用,并且如果鼠标事件在绘图对象上方,该绘图对象将触发一个选择事件。

    设置 pickradius 将增加一个以点为单位的 epsilon 容差,如果绘图数据在鼠标事件的 epsilon 范围内,绘图对象将触发一个事件。对于某些绘图对象,如线条和集合块,绘图对象可能会向生成的选择事件提供额外的数据,例如,选择事件的 epsilon 范围内的数据的索引。

  • function - 如果 picker 是可调用对象,它是一个用户提供的函数,用于确定绘图对象是否被鼠标事件击中。

    hit, props = picker(artist, mouseevent)
    

    用于确定命中测试。如果鼠标事件在绘图对象上方,返回 hit=True,并且 props 是一个字典,包含您希望添加到 PickEvent 属性的属性。

在通过设置“picker”属性启用绘图对象进行选择后,您需要连接到图形画布的 pick_event 以在鼠标按下事件时获取选择回调。例如:

def pick_handler(event):
    mouseevent = event.mouseevent
    artist = event.artist
    # now do something with this...

传递给回调函数的选择事件(matplotlib.backend_bases.PickEvent)总是带有两个属性:

mouseevent

生成选择事件的鼠标事件。

鼠标事件反过来又具有 x 和 y(显示空间中的坐标,例如从左下角开始的像素)和 xdata、ydata(数据空间中的坐标)等属性。此外,您可以获取有关按下了哪些按钮、按下了哪些键、鼠标位于哪个 Axes 上等信息。详见 matplotlib.backend_bases.MouseEvent。

artist

生成选择事件的 matplotlib.artist。

此外,某些绘图对象(如 Line2D 和 PatchCollection)可能会附加额外的元数据,例如符合选择器条件的数据索引(例如,线中在指定 epsilon 容差内的所有点)。

下面的示例展示了这些方法。

注意

这些示例演示了 Matplotlib 的交互功能,这不会出现在静态文档中。请在您的机器上运行此代码以查看交互性。

您可以复制粘贴部分内容,或使用页面底部的链接下载整个示例。

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

from matplotlib.image import AxesImage
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)
ax1.set_title('click on points, rectangles or text', picker=True)
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)
for label in ax2.get_xticklabels():  # Make the xtick labels pickable.
    label.set_picker(True)


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


fig.canvas.mpl_connect('pick_event', onpick1)
click on points, rectangles or text

使用自定义命中测试函数进行选择#

您可以通过将 picker 设置为可调用函数来定义自定义选择器。该函数具有以下签名:

hit, props = func(artist, mouseevent)

用于确定命中测试。如果鼠标事件在绘图对象上方,返回 hit=True,并且 props 是一个字典,包含您希望添加到 PickEvent 属性的属性。

def line_picker(line, mouseevent):
    """
    Find the points within a certain distance from the mouseclick in
    data coords and attach some extra attributes, pickx and picky
    which are the data points that were picked.
    """
    if mouseevent.xdata is None:
        return False, dict()
    xdata = line.get_xdata()
    ydata = line.get_ydata()
    maxd = 0.05
    d = np.sqrt(
        (xdata - mouseevent.xdata)**2 + (ydata - mouseevent.ydata)**2)

    ind, = np.nonzero(d <= maxd)
    if len(ind):
        pickx = xdata[ind]
        picky = ydata[ind]
        props = dict(ind=ind, pickx=pickx, picky=picky)
        return True, props
    else:
        return False, dict()


def onpick2(event):
    print('onpick2 line:', event.pickx, event.picky)


fig, ax = plt.subplots()
ax.set_title('custom picker for line data')
line, = ax.plot(rand(100), rand(100), 'o', picker=line_picker)
fig.canvas.mpl_connect('pick_event', onpick2)
custom picker for line data

散点图上的选择#

散点图由 PathCollection 支持。

x, y, c, s = rand(4, 100)


def onpick3(event):
    ind = event.ind
    print('onpick3 scatter:', ind, x[ind], y[ind])


fig, ax = plt.subplots()
ax.scatter(x, y, 100*s, c, picker=True)
fig.canvas.mpl_connect('pick_event', onpick3)
pick event demo

选择图像#

使用 Axes.imshow 绘制的图像是 AxesImage 对象。

fig, ax = plt.subplots()
ax.imshow(rand(10, 5), extent=(1, 2, 1, 2), picker=True)
ax.imshow(rand(5, 10), extent=(3, 4, 1, 2), picker=True)
ax.imshow(rand(20, 25), extent=(1, 2, 3, 4), picker=True)
ax.imshow(rand(30, 12), extent=(3, 4, 3, 4), picker=True)
ax.set(xlim=(0, 5), ylim=(0, 5))


def onpick4(event):
    artist = event.artist
    if isinstance(artist, AxesImage):
        im = artist
        A = im.get_array()
        print('onpick4 image', A.shape)


fig.canvas.mpl_connect('pick_event', onpick4)

plt.show()
pick event demo

脚本总运行时间: (0 分钟 1.814 秒)

由 Sphinx-Gallery 生成的画廊