简介
本实验旨在向你介绍 Matplotlib 中的拾取概念。拾取艺术家对象的能力是一个强大的工具,可用于构建响应用户操作的交互式可视化。我们将介绍简单拾取、使用自定义命中测试函数进行拾取、在散点图上进行拾取以及拾取图像。
虚拟机提示
虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。
有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。
如果你在学习过程中遇到问题,请随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。
简单拾取、线条、矩形和文本
我们将通过设置艺术家对象的“picker”属性来启用简单拾取。如果鼠标事件发生在艺术家对象上方,这将使该艺术家对象触发一个拾取事件。我们将创建一个包含一条线、一个矩形和一段文本的简单绘图,并对这些艺术家对象中的每一个启用拾取功能。
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)
## 拾取矩形。
ax2.bar(range(10), rand(10), picker=True)
for label in ax2.get_xticklabels(): ## 使 x 轴刻度标签可拾取。
label.set_picker(True)
创建自定义命中测试函数
在这一步中,我们将通过将 picker 设置为一个可调用函数来定义一个自定义拾取器。该函数将确定艺术家对象是否被鼠标事件命中。如果鼠标事件发生在艺术家对象上方,我们将返回 hit=True,并且 props 是一个字典,其中包含你想要添加到 .PickEvent 属性中的属性。
def line_picker(line, mouseevent):
"""
在数据坐标中找到距离鼠标点击一定距离内的点,并附加一些额外的属性,pickx 和 picky,
它们是被拾取的数据点。
"""
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)
在散点图上进行拾取
散点图由 ~matplotlib.collections.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)
拾取图像
使用 .Axes.imshow 绘制的图像是 ~matplotlib.image.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)
总结
在本实验中,我们学习了如何在 Matplotlib 中对各种艺术家对象启用拾取功能,包括线条、矩形、文本、散点图和图像。我们还学习了如何定义自定义命中测试函数,以实现更复杂的拾取行为。这个强大的工具使我们能够创建响应用户操作的交互式可视化。