Matplotlib - 事件处理



在一般的编程中,**事件**被定义为对象状态的改变,当用户与图形用户界面组件交互时发生,从而触发应用程序的响应。例如点击按钮、移动鼠标、在键盘上打字、从列表中选择项目或滚动页面——这些活动都是事件,描述了源状态的改变。

而**事件处理**是交互式软件应用程序的支柱。它是一种控制对这些事件响应的机制,确定特定事件发生时应该发生什么。

Matplotlib 中的事件处理

Matplotlib 与各种用户界面工具包协同工作,包括 wxPython、Tkinter、Qt、GTK 和 MacOSX。为了确保跨不同界面的平移和缩放等交互式功能的一致支持,Matplotlib 使用了**GUI 中立**的事件处理 API。这个 API 最初基于**GTK** 模型,它是 Matplotlib 支持的第一个用户界面。

连接到事件

Matplotlib 中**事件处理**的主要思想是将回调函数连接到事件。当发生特定事件(例如鼠标点击或按键)时,回调函数会被执行。这种机制使你能够响应用户交互并实现自定义行为。

如果需要,你可以使用从 mpl_connect 方法获得的连接 ID 断开回调。

fig.canvas.mpl_disconnect(cid)

示例

此示例演示了一个基本实现,它在 Matplotlib 绘图上打印鼠标点击位置和按下的按钮。

import matplotlib.pyplot as plt
import numpy as np

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

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

# Plot the data
ax.plot(x, y)

# Define a callback function to handle events
def onclick(event):
   print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
      ('double' if event.dblclick else 'single', event.button,
      event.x, event.y, event.xdata, event.ydata))

# Connect the event handler to the figure canvas
cid = fig.canvas.mpl_connect('button_press_event', onclick)

plt.show()

输出

执行上述程序后,你将获得以下输出:

event_handling_ex1
single click: button=1, x=271, y=266, xdata=3.220737, ydata=0.485644
single click: button=1, x=218, y=226, xdata=2.146083, ydata=0.200062
single click: button=3, x=218, y=226, xdata=2.146083, ydata=0.200062
single click: button=1, x=360, y=245, xdata=5.025346, ydata=0.335713

观看下面的视频以观察此示例的工作原理。

event_handling_ex1 gif

Matplotlib 中的常见事件

Matplotlib 支持各种事件,每个事件都由一个特定的类表示:

  • **button_press_event** - 当按下鼠标按钮时触发。

  • **button_release_event** - 当释放鼠标按钮时触发。

  • **close_event** - 当图形关闭时触发。

  • **draw_event** - 当画布已绘制但屏幕小部件尚未更新时触发。

  • **key_press_event** - 当按下键时触发。

  • **key_release_event** - 当释放键时触发。

  • **motion_notify_event** - 当鼠标移动时触发。

  • **pick_event** - 当选择画布中的图形对象时触发。

  • **resize_event** - 当图形画布大小调整时触发。

  • **scroll_event** - 当滚动鼠标滚轮时触发。

  • **figure_enter_event** - 当鼠标进入新图形时触发。

  • **figure_leave_event** - 当鼠标离开图形时触发。

  • **axes_enter_event** - 当鼠标进入新的坐标轴时触发。

  • **axes_leave_event** - 当鼠标离开坐标轴时触发。

通过使用这些事件,你可以在 matplotlib 中创建动态和交互式的可视化效果。

事件属性

所有 Matplotlib 事件都继承自**matplotlib.backend_bases.Event** 类,该类具有**name**、**canvas** 和**guiEvent** 等属性。**MouseEvent** 的常见属性包括**x**、**y**、**inaxes**、**xdata** 和**ydata**。

示例

让我们看看这个简单的示例,其中在绘图上每次鼠标按下都会生成一条线段。

from matplotlib import pyplot as plt
import numpy as np

# LineBuilder Class
# It creats line segments based on mouse clicks.
class LineBuilder:
   def __init__(self, line):
      self.line = line
      self.xs = list(line.get_xdata())
      self.ys = list(line.get_ydata())
      self.cid = line.figure.canvas.mpl_connect('button_press_event', self)

   def __call__(self, event):
      if event.inaxes != self.line.axes:
         return
      self.xs.append(event.xdata)
      self.ys.append(event.ydata)
      self.line.set_data(self.xs, self.ys)
      self.line.figure.canvas.draw()

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

# Set the title
ax.set_title('Click to Build Line Segments')

# empty line
line, = ax.plot([0], [0])  

# Create an instance for LineBuilder class
linebuilder = LineBuilder(line)

# Show the Plot
plt.show()

输出

执行上述程序后,你将获得以下图形,点击此图形以观察此示例的工作原理:

Image

观看下面的视频以观察此示例的工作原理。

event_handling_ex2 GIF

检测鼠标移动

要检测鼠标何时进入或离开图形或坐标轴,我们可以连接到图形/坐标轴进入/离开事件。

示例

以下是一个示例,演示了如何在鼠标进入或离开图形的特定区域时更改框架颜色。

import matplotlib.pyplot as plt

def enter_axes(event):
   event.inaxes.patch.set_facecolor('yellow')
   event.canvas.draw()

def leave_axes(event):
   event.inaxes.patch.set_facecolor('white')
   event.canvas.draw()

def enter_figure(event):
   event.canvas.figure.patch.set_facecolor('red')
   event.canvas.draw()

def leave_figure(event):
   event.canvas.figure.patch.set_facecolor('grey')
   event.canvas.draw()

fig, axs = plt.subplots(2, figsize=(7, 4))
fig.suptitle('Mouse Hover Over Figure or Axes to Trigger Events')

fig.canvas.mpl_connect('figure_enter_event', enter_figure)
fig.canvas.mpl_connect('figure_leave_event', leave_figure)
fig.canvas.mpl_connect('axes_enter_event', enter_axes)
fig.canvas.mpl_connect('axes_leave_event', leave_axes)

plt.show()
输出

执行上述程序后,你将获得以下输出:

event_handling_ex3

观看下面的视频以观察此示例的工作原理。

event_handling_ex3.gif

示例

以下是一个示例,演示了如何使用 Matplotlib 显示鼠标释放事件坐标

from matplotlib import pyplot as plt

plt.rcParams['backend'] = 'TkAgg'
plt.rcParams["figure.figsize"] = [7, 4]
plt.rcParams["figure.autolayout"] = True

# Define a callback function to handle events
def onclick(event):
   print(event.button, event.xdata, event.ydata)

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

# Plot the data
ax.plot(range(10))

# Connect the event handler to the figure canvas
fig.canvas.mpl_connect('button_release_event', onclick)

# Show the Plot
plt.show()
输出

执行上述代码后,我们将获得以下输出:

event_handling_ex4

观看下面的视频以观察此示例的工作原理。

event_handling_ex4.gif
广告