拾取事件演示#

可以通过设置艺术家(例如,Matplotlib Line2D、Text、Patch、Polygon、AxesImage 等)的“picker”属性来启用拾取。

“picker”属性有多种含义

  • None - 此艺术家禁用拾取(默认值)

  • bool - 如果为 True,则启用拾取,如果鼠标事件在艺术家上,艺术家将触发拾取事件。

    设置 pickradius 将以点为单位添加一个 epsilon 容差,如果艺术家数据在鼠标事件的 epsilon 内,艺术家将触发一个事件。对于某些艺术家,如线条和面片集合,艺术家可能会在生成的拾取事件中提供额外的數據,例如,在拾取事件的 epsilon 内的数据索引

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

    hit, props = picker(artist, mouseevent)
    

    确定命中测试。如果鼠标事件在艺术家上,则返回 hit=Trueprops 是一个字典,其中包含要添加到 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=Trueprops 是一个字典,其中包含要添加到 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.479 秒)

由 Sphinx-Gallery 生成的图库