之前写过一篇pick_event的文章,这篇算是升级版。O(∩_∩)O哈哈~
这次不用点击,当鼠标移动进入柱状图的某一个柱子时,改变柱子颜色。
这里有两种方法,都是使用matplotlib.patches模块。其实这两种方法都是一个意思,只是实现的方法一种是用的Rectangle,另一种是用Polygon实现。
先使用Rectangle来实现
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
import numpy as np
from matplotlib.patches import Rectangle, Polygon
import matplotlib.pyplot as plt
'''此处实现的是Rectangle来改变柱形颜色'''
def motion_notify(event):
# 先检查鼠标是否移动在某个柱形上
bools_list = list(map(lambda x: x.contains_point((event.x, event.y)), container_bar))
try:
ind = bools_list.index(True) # 获取鼠标所在柱形的坐标
bar = container_bar[ind] # 获取索引对应的柱形图
# 分别获取当前柱形的左下角的x、y值和宽度、高度
l = bar.get_x()
b = bar.get_y()
w = bar.get_width()
h = bar.get_height()
except ValueError: # 当鼠标没有进入到柱形时,会报ValueError错误
l, b, w, h = 0, 0, 0, 0
rec.set_bounds(l, b, w, h) # 设置矩形的边界
event.canvas.draw()
if __name__ == "__main__":
a = np.random.randint(130, size=6) # 随机生成6个0~130之间的数字
le = np.arange(a.shape[0])
container_bar = plt.bar(le, a)
rec = Rectangle((0, 0), width=0, height=0, facecolor="y") # 初始化Rectangle
plt.gca().add_patch(rec)
plt.gcf().canvas.mpl_connect("motion_notify_event", motion_notify)
plt.show()
Polygon方法实现
def motion_notify(event):
bools_list = list(map(lambda x: x.contains_point((event.x, event.y)), container_bar))
try:
ind = bools_list.index(True)
bar = container_bar[ind]
bbox = bar.get_bbox() #
x0, x1, y0, y1 = bbox.x0, bbox.x1, bbox.y0, bbox.y1
xs = (x0, x1, x1, x0)
ys = (y1, y1, y0, y0)
except ValueError:
xs = (0, 0, 0, 0)
ys = (0, 0, 0, 0)
polygon.set_xy(list(zip(xs, ys))) # 将xs和ys一一对应,生成矩形四个端点的坐标。第一个端点是从矩形的左上角开始的
event.canvas.draw()
if __name__ == "__main__":
a = np.random.randint(100, size=6)
length = np.arange(a.shape[0])
container_bar = plt.bar(length, a)
polygon = Polygon([[0, 0], [0, 0]], facecolor="y") # 使用Polygon方法改变颜色
plt.gca().add_patch(polygon)
plt.gcf().canvas.mpl_connect("motion_notify_event", motion_notify)
plt.show()