拾取事件演示#

您可以通过设置艺术家(例如,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(数据空间中的坐标)之类的属性。此外,您可以获取有关按下了哪些按钮、按下了哪些键、鼠标位于哪个轴上方等信息。有关详细信息,请参见 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 分钟 2.043 秒)

Sphinx-Gallery 生成的图库