Matplotlib中的事件处理详解与实战

简介: Matplotlib是Python的绘图库,可以生成所需的出版质量级别的图形,本文将详细介绍Matplotlib中的事件处理,并通过实战了解其用法。

前言

Matplotlib 作为 Python 的绘图库,能否直接进行事件处理呢?答案是肯定的,本文将介绍在 Matplotlib 中事件的处理。

Matplotlib 与许多用户界面工具包配合使用,包括 wxpython、tkinter、qt 以及gtk 等,因此不必针对不同的用户界面编写功能重复的代码。Matplotlib 与标准 GUI 事件相比,触发的事件更丰富,其包括事件发生在哪个轴等信息。

事件连接

要使 Matplotlib 可以接收事件,需要编写一个回调函数(在事件发生时会进行调用),然后将函数连接到事件管理器。

以鼠标事件为例,我们通过以下程序实现打印鼠标点击的位置和按下了哪个按钮的功能:

frommatplotlibimportpyplotaspltimportnumpyasnpfig, ax=plt.subplots()
ax.scatter(np.random.rand(100), np.random.rand(100))
# 编写回调函数defonclick(event):
print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%          ('double'ifevent.dblclickelse'single', event.button,
event.x, event.y, event.xdata, event.ydata))
# 将回调函数连接到事件管理器上cid=fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()

FigureCanvasBase.mpl_connect 方法返回该事件的连接 id,此 id 可用于断开回调:  

fig.canvas.mpl_disconnect(cid)

可以使用 Matplotlib 连接更多事件,具体参见官方文档,在此不在一一列举。需要注意的是,连接到“key_press_event”和“key_release_event”事件时,Matplotlib 使用不同用户界面工具包之间可能会出现不一致。可以通过查看键盘快捷键,可以看到 Matplotlib 默认附加了一些按键回调。

事件属性

所有 Matplotlib 事件都继承自基类 matplotlib.backend_bases.Event,它包含以下属性:

属性名

含义

name

事件名

canvas

FigureCanvas 实例生成事件

guiEvent

触发 Matplotlib 事件的GUI事件

我们以事件处理中最常见的事件按键按下/释放事件和鼠标按下/释放/移动事件为例,利用事件属性。 处理这些事件的 KeyEvent 和 MouseEvent 类都是从 LocationEvent 派生的,它具有以下属性:

属性名

含义

x,y

鼠标距画布左下角的距离(以像素为单位)

inaxes

鼠标所在的 Axes 实例(如果有)

xdata, ydata

鼠标在数据坐标中的位置

为了对比属性 x、y 和 xdata、ydata 的区别,使用以下程序进行说明,此程序会在鼠标单击时,在画布上显示鼠标事件的 x、y、xdata、和 ydata 属性:

frommatplotlibimportpyplotaspltclassTextBuilder:
def__init__(self, line):
self.text=textself.content=self.text.get_text()
self.cid=text.figure.canvas.mpl_connect('button_press_event', self)
def__call__(self, event):
print('click', event)
ifevent.inaxes!=self.text.axes: returnself.text.set_x(event.xdata)
self.text.set_y(event.ydata)
self.text.set_text('x:{},y:{},xdata:{:.2f},ydata:{:.2f}'.format(event.x,event.y,event.xdata,event.ydata))
self.text.figure.canvas.draw()
fig, ax=plt.subplots()
ax.set_title('click to show event attribute')
text=plt.text([0], [0], '')
textbuilder=TextBuilder(text)
plt.show()

运行程序后,当在画布上单击时,会在鼠标点击处,绘制出事件的 x、y、xdata、和 ydata 属性值:

绘图154.png

接下来,我们编写另一个示例程序,此程序会在每次按下鼠标时绘制一条线段:  

frommatplotlibimportpyplotaspltclassLineBuilder:
def__init__(self, line):
self.line=lineself.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):
print('click', event)
ifevent.inaxes!=self.line.axes: returnself.xs.append(event.xdata)
self.ys.append(event.ydata)
self.line.set_data(self.xs, self.ys)
self.line.figure.canvas.draw()
fig, ax=plt.subplots()
ax.set_title('click to build line segments')
line, =ax.plot([0], [0])  # empty linelinebuilder=LineBuilder(line)
plt.show()

运行程序后,当在画布上单击时,会在每次按下鼠标时绘制一条线段:

绘图155.png

实战:直方图中矩形的拖拽

接下来,为了更好的理解 Matplotlib 中的事件,编写使用 Rectangle 实例初始化的可拖动矩形类,在拖动时同时移动矩形位置。

在拖拽前,需要存储矩形的原始位置,该位置存储可以使用 rect.xy 获得,然后需要连接按下(press)、运动(motion)和释放(release)鼠标事件。 当按下鼠标时,检查单击是否发生在矩形上,如果是,则将矩形位置和鼠标单击的位置存储在数据坐标中。 在运动事件回调中,计算鼠标移动的距离 deltax 和 deltay,并利用这些值计算矩形新的位置,设置矩形透明度,最后重绘图。在鼠标释放事件中,需要将存储的数据重置为 None,并恢复矩形透明度:

importnumpyasnpimportmatplotlib.pyplotaspltclassDraggableRectangle:
def__init__(self, rect):
self.rect=rectself.press=Nonedefconnect(self):
"""Connect to all the events we need."""self.cidpress=self.rect.figure.canvas.mpl_connect(
'button_press_event', self.on_press)
self.cidrelease=self.rect.figure.canvas.mpl_connect(
'button_release_event', self.on_release)
self.cidmotion=self.rect.figure.canvas.mpl_connect(
'motion_notify_event', self.on_motion)
defon_press(self, event):
"""Check whether mouse is over us; if so, store some data."""ifevent.inaxes!=self.rect.axes:
returncontains, attrd=self.rect.contains(event)
ifnotcontains:
returnprint('event contains', self.rect.xy)
self.press=self.rect.xy, (event.xdata, event.ydata)
defon_motion(self, event):
"""Move the rectangle if the mouse is over us."""ifself.pressisNoneorevent.inaxes!=self.rect.axes:
return        (x0, y0), (xpress, ypress) =self.pressdx=event.xdata-xpressdy=event.ydata-ypressself.rect.set_x(x0+dx)
self.rect.set_y(y0+dy)
self.rect.set_alpha(0.5)
self.rect.figure.canvas.draw()
defon_release(self, event):
"""Clear button press information."""self.press=Noneself.rect.set_alpha(1.)
self.rect.figure.canvas.draw()
defdisconnect(self):
"""Disconnect all callbacks."""self.rect.figure.canvas.mpl_disconnect(self.cidpress)
self.rect.figure.canvas.mpl_disconnect(self.cidrelease)
self.rect.figure.canvas.mpl_disconnect(self.cidmotion)
fig, ax=plt.subplots()
rects=ax.bar(range(10), 20*np.random.rand(10))
drs= []
forrectinrects:
dr=DraggableRectangle(rect)
dr.connect()
drs.append(dr)
plt.show()

运行程序后,可以在画布上使用鼠标拖拽矩形,并且在拖拽过程中矩形透明度会降低以显式显示正在拖拽的矩形:

绘图156.png

相关文章
|
4月前
|
数据可视化 Python
Python数据可视化利器Matplotlib实战教程
本文将介绍如何使用Python中强大的数据可视化工具Matplotlib,通过丰富的示例和实战操作,帮助读者快速掌握Matplotlib的基本用法和高级技巧,实现数据可视化的艺术。
|
4月前
|
数据可视化 数据挖掘 Python
【数据分析与可视化】Matplotlib中动态rc参数设置详解与实战(图文解释 附源码)
【数据分析与可视化】Matplotlib中动态rc参数设置详解与实战(图文解释 附源码)
194 0
|
2月前
|
数据可视化 数据挖掘 Linux
震撼发布!Python数据分析师必学,Matplotlib与Seaborn数据可视化实战全攻略!
【7月更文挑战第22天】数据科学中,Matplotlib和Seaborn是Python的可视化主力。Matplotlib用于基础图表,如示例中的折线图;Seaborn则强化统计图形,如分布图。两者结合能创建复杂的可视化,如显示趋势与分布的同一图表。通过学习和运用这些工具,数据分析师能提升效率,更好地讲述数据故事。
39 2
|
4月前
|
数据可视化 数据处理 Python
Python数据可视化:Matplotlib库的使用与实战
Python数据可视化:Matplotlib库的使用与实战
65 0
|
4月前
|
数据采集 数据处理 Python
Matplotlib实战:从数据处理到图表展示
【4月更文挑战第17天】本文介绍了使用Matplotlib进行数据图表展示的实战步骤,从数据处理(如使用pandas清洗数据)到选择图表类型,再到使用Matplotlib绘制折线图并进行美化定制(如调整线条样式、添加图例、设置坐标轴范围和添加网格)。最后,文章还展示了如何保存图表为图片文件。通过本文,读者可掌握利用Matplotlib创建精美图表的技能。
|
4月前
|
人工智能 数据可视化 测试技术
Python数据可视化之Matplotlib实战Python中的装饰器:优雅而强大的函数增强工具
Python是一门强大的编程语言,它在数据科学和人工智能领域有着广泛应用。Matplotlib是Python中最常用的数据可视化库之一,它可以帮助开发者将复杂的数据呈现出来,以更好的展示和分析数据。本文将通过实例,介绍如何使用Matplotlib进行数据可视化。 在Python编程中,装饰器是一种强大的工具,可以用来增强函数的功能而不改变其结构。本文将深入探讨Python中装饰器的原理、应用及实例,帮助读者更好地理解和运用这一技术。
|
存储 前端开发 索引
Matplotlib 中文用户指南 7.3 事件处理及拾取
事件处理及拾取 原文:Event handling and picking 译者:飞龙 协议:CC BY-NC-SA 4.0 matplotlib 使用了许多用户界面工具包(wxpython,tkinter,qt4,gtk 和 macosx),为了支持交互式平移和缩放图形等功能,拥有一套 API 通过按键和鼠标移动与图形交互,并且『GUI中立』,对开发人员十分有帮助,所以我们不必重复大量的代码来跨不同的用户界面。
1385 0
|
9天前
|
数据可视化 Python
Python中的数据可视化:使用Matplotlib绘制图表
【9月更文挑战第11天】在这篇文章中,我们将探索如何使用Python的Matplotlib库来创建各种数据可视化。我们将从基本的折线图开始,然后逐步介绍如何添加更多的功能和样式,以使您的图表更具吸引力和信息量。无论您是数据科学家、分析师还是任何需要将数据转化为视觉形式的专业人士,这篇文章都将为您提供一个坚实的起点。让我们一起潜入数据的海洋,用视觉的力量揭示其背后的故事。
33 16
|
1天前
|
数据可视化 数据挖掘 API
使用Python进行数据可视化:探索Matplotlib和Seaborn库
【9月更文挑战第19天】在数据科学领域,将复杂的数据集转换成直观、易懂的图形是一项基本而关键的技能。本文旨在通过Python编程语言介绍两个强大的数据可视化库——Matplotlib和Seaborn,以及它们如何帮助数据分析师和研究人员揭示数据背后的故事。我们将从基础概念讲起,逐步深入到高级技巧,确保无论读者的背景如何,都能获得必要的知识和启发,以在自己的项目中实现有效的数据可视化。
|
9天前
|
机器学习/深度学习 数据采集 监控
Pandas与Matplotlib:Python中的动态数据可视化
Pandas与Matplotlib:Python中的动态数据可视化