先叨叨两句,也算让自己涨涨记性:需要使用matplotlib实现某些交互功能,因为是新手所以着实费了一番功夫。这也提醒自己时候在看官网Demo的时候一定要把每行代码,每个参数都要了解透彻。
这里先简单说一下matplotlib的事件选取:
matplotlib有下面
事件名称 | 类和描述 |
'button_press_event' | MouseEvent - 鼠标按钮被按下 |
‘button_release_event’ | MouseEvent - 鼠标按钮被释放 |
‘draw_event’ | DrawEvent - 画布绘图 |
‘key_press_event’ | KeyEvent - 按键被按下 |
‘key_release_event’ | KeyEvent - 案件被释放 |
‘motion_notify_event’ | MouseEvent - 鼠标移动 |
‘pick_event’ | PickEvent - 话不中的对象被拾取 |
‘resize_event’ | ResizeEvent - 图形画布大小改变 |
‘scroll_event’ | MouseEvent - 鼠标滚轴被滚动 |
‘figure_enter_event’ | LocationEvent - 鼠标进入新的图形 |
‘figure_leave_event’ | LocationEvent - 鼠标离开图形 |
‘axes_enter_event’ | LocationEvent - 鼠标进入新的轴域 |
‘axes_leave_event’ | LocationEvent - 鼠标离开轴域 |
如果要触发事件需要创建一个回调函数,就是def(event), 然后使用FigureCanvas的mpl_connect()方法进行连接。
import matplotlib.pyplot as plt
import numpy as np
# 先创建一个回调函数
def onclick(event):
print('x = %s, y = %s, xdata = %s, y = %s' %
(event.x, event.y, event.xdata, event.ydata))
if __name__ == '__main__':
# matplotlib不会直接显示中文,所以这里这只一下
plt.rcParams['font.sans-serif'] = ['SimHei']
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('这是一张空白画板')
ax.plot()
# 下面进行事件连接操作
fig.canvas.mpl_connect('button_press_event', onclick)
# 其实mpl_connect只能接受两个参数,一个是你想触发的事件名称,一个就是回调函数
plt.show()
运行结果如下:
此时你点击画板的任何有效位置(就是坐标内的空白处),都会触发‘button_press_event’事件,后台会进行相应的打印
其实整个连接主要就是两点:回调函数和使用FigureCanvas的mpl_connect('事件名称', 回调函数)方法进行连接
这里补充一点,mpl_connect()是有返回值的,只不过是一个int型数字
下面就直奔主题了:
我需要实现的是画出柱状图(plt.bar()),然后鼠标对图中的某个矩形进行选取,被选中的矩形就会变成别的颜色,以示区别。
下面是代码:
#! /usr/bin/python3
# -*- coding:utf-8 -*-
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np
class BarBrowser(object):
def __init__(self):
self.xy = 0
self.width = 0
self.height = 0
# 这里是为了让鼠标选中画板中的矩形,用来进行变色的。需要注意visible参数
# visible是设置图形是否直接在画板进行显示的,如果设置为True,运行程序,
# 则会直接进行显示。
self.selected = ax.add_artist(Rectangle(rects[0].get_xy(),
rects[0].get_width(),
rects[0].get_height(),
color='g', visible=False))
def enter_axes(self, event):
if not event.artist:
return True
self.xy = event.artist.xy
self.width = event.artist.get_width()
self.height = event.artist.get_height()
self.selected.set_visible(True)
self.selected.set_xy(self.xy)
self.selected.set_height(self.height)
self.selected.set_alpha(0.7)
fig.canvas.draw()
if __name__ == '__main__':
plt.rcParams['font.sans-serif'] = ['SimHei']
fig = plt.figure()
ax = fig.add_subplot(111)
# 下面的两个变量是画板上要展示的数据
theyear = ['1月', '2月', '3月', '4月', '5月', '6月',
'7月', '8月', '9月', '10月', '11月', '12月']
peoplesum = [855, 770, 808, 793, 850, 795, 887, 909, 824, 879, 802, 827]
xno = np.arange(len(theyear))
# 绘制柱形图。这里需要注意picker属性,它决定了'pick_event'是否被激活
# 取值可以是浮点型、布尔值或者函数。这里我们设置为True。
rects = ax.bar(xno, peoplesum, picker=True)
plt.xticks(xno, theyear) # 设置x轴坐标
browser = BarBrowser()
fig.canvas.mpl_connect('pick_event', browser.enter_axes)
plt.show()
运行结果如下:
当你选择其中的某个矩形,被选中的矩形就会编程绿色(颜色随意设置)。
在整个绘制过程中需要注意一下几个地方:
plt.bar()的visible参数:如果取值为浮点型,表示与鼠标点击位置的误差。如果是布尔值则表示时间被激活,不然是不会有结果的
至于取值为函数,这里我也没弄明白,就不误导了
还有就是这里使用到了matplotlib的patches模块中的Rectangle函数进行矩形的绘制,就是在选中的矩形上重新绘制一个一样的矩形。
现在基本就实现了我想要的功能。如果有需要改正的地方希望能够指正。