如何为Matplotlib柱状图添加悬停提示以显示时间与温度数据
实现Matplotlib柱状图的鼠标悬停显示功能
要给你的柱状图添加鼠标悬停显示时间和温度的功能,你可以利用Matplotlib的事件监听机制,动态更新标注内容。以下是修改后的完整代码:
import numpy as np import pandas as pd import datetime import matplotlib.pyplot as plt ts = ['25/02/2023 0:00', '25/02/2023 0:01', '25/02/2023 0:02', '25/02/2023 0:03', '25/02/2023 0:04', '25/02/2023 0:05', '25/02/2023 0:06', '25/02/2023 0:07', '25/02/2023 0:08', '25/02/2023 0:09', '25/02/2023 0:10', '25/02/2023 0:11', '25/02/2023 0:12', '25/02/2023 0:13', '25/02/2023 0:14', '25/02/2023 0:15', '25/02/2023 0:16', '25/02/2023 0:17', '25/02/2023 0:18', '25/02/2023 0:19', '25/02/2023 0:20', '25/02/2023 0:21', '25/02/2023 0:22', '25/02/2023 0:23', '25/02/2023 0:24', '25/02/2023 0:25', '25/02/2023 0:26', '25/02/2023 0:27', '25/02/2023 0:28', '25/02/2023 0:29', '25/02/2023 0:30'] temp = ['0', '-21', '20', '30', '-40', '50', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '-18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '68'] df = pd.DataFrame(list(zip(ts, temp)), columns = ['ts', 'temp']) df['temp']=df['temp'].astype(float) df1 = df.reset_index() df100 = pd.DataFrame(data=df1) df100['ts'] = pd.to_datetime(df100['ts']) df100['ts'] = df100['ts'].dt.strftime('%d-%m--%H:%M') # 获取绘图的Axes对象 ax = df100.plot.bar(x="ts", y="temp", rot=90, figsize=(12, 6)) plt.subplots_adjust(bottom=0.2) plt.xlabel("Time") plt.ylabel("temp") plt.title('Temperature') # 创建初始隐藏的标注 annot = ax.annotate("", xy=(0,0), xytext=(20,20), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")) annot.set_visible(False) # 更新标注内容和位置的函数 def update_annot(rect, idx): x = rect.get_x() + rect.get_width() / 2 y = rect.get_y() + rect.get_height() annot.xy = (x, y) # 获取对应的时间和温度 time_val = df100['ts'].iloc[idx] temp_val = df100['temp'].iloc[idx] text = f"时间: {time_val}\n温度: {temp_val}°C" annot.set_text(text) annot.get_bbox_patch().set_alpha(0.9) # 鼠标悬停处理函数 def hover(event): vis = annot.get_visible() if event.inaxes == ax: # 获取所有柱子 rects = ax.patches for idx, rect in enumerate(rects): if rect.contains(event)[0]: update_annot(rect, idx) annot.set_visible(True) plt.draw() return if vis: annot.set_visible(False) plt.draw() # 鼠标离开处理函数 def hover_off(event): annot.set_visible(False) plt.draw() # 绑定事件 fig = plt.gcf() fig.canvas.mpl_connect("motion_notify_event", hover) fig.canvas.mpl_connect("axes_leave_event", hover_off) plt.show(block=True)
关键部分说明:
- 获取Axes和柱子对象:通过
ax = df100.plot.bar(...)拿到绘图的轴对象,再通过ax.patches获取所有柱状图的矩形元素 - 创建标注:
annotate生成一个带箭头的悬浮框,初始设为不可见 - 悬停事件处理:
hover函数监听鼠标移动,判断鼠标是否在某个柱子上,若是则更新标注的位置和内容并显示;hover_off函数在鼠标离开轴区域时隐藏标注 - 事件绑定:把两个处理函数分别绑定到鼠标移动事件和轴离开事件上
内容的提问来源于stack exchange,提问作者Ashu
相关产品推荐
相关产品推荐

