python+matplotlib实现在图中鼠标指向标注点处显示标注信息(标注信息动态显示)

您所在的位置:网站首页 python文本标注 python+matplotlib实现在图中鼠标指向标注点处显示标注信息(标注信息动态显示)

python+matplotlib实现在图中鼠标指向标注点处显示标注信息(标注信息动态显示)

2023-11-19 04:37| 来源: 网络整理| 查看: 265

说明

此篇为 一次python画图经历——涉及 matplotlib 的折线图,散点图,图中标注文字信息,设置横坐标密度,调整横坐标旋转角度,文字大小、各部分颜色、保存形式、美化调整 的延续,当时自以为很好地处理了标注信息的问题,结果发现,当需要标注的点很多很密集的时候,画出来的图会很糟糕:

在这里插入图片描述 因此重新想了一个办法,加入鼠标交互功能,当鼠标指针指向标注点时,将标注信息显示出来,不指向时不显示标注信息,以下为实现过程。

标注信息动态显示 数据

在这里插入图片描述

代码 import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as ticker # ---------- 数据预处理 ---------- file_path = './example_csdn_processed.csv' df_all = pd.DataFrame(pd.read_csv(file_path, encoding='gbk')) df_all = df_all.set_index(pd.DatetimeIndex(pd.to_datetime(df_all.time))) x = df_all['time'] y1 = df_all['data'] y2 = df_all["buy"] y3 = df_all["sell"] y_condition = list(df_all["操作"]) text1 = [] for i in range(len(x)): if (df_all['操作'][i] != 0) and (df_all['操作'][i] == "买"): str_info = '价格: ' + str(df_all['价格'][i]) + '\n' + '数量: ' + str(df_all['数量'][i]) + '\n' + '操作: ' + str(df_all['操作'][i]) text1.append(str_info) else: text1.append(" ") text2 = [] for i in range(len(x)): if (df_all['操作'][i] != 0) and (df_all['操作'][i] == "卖"): str_info = '价格: ' + str(df_all['价格'][i]) + '\n' + '数量: ' + str(df_all['数量'][i]) + '\n' + '操作: ' + str(df_all['操作'][i]) text2.append(str_info) else: text2.append(" ") # ---------- 画图 ---------- fig, ax = plt.subplots() # 折线图 ax.plot(x, y1, color='royalblue', lw=2.5, label='data') # 折线图上的散点 ax.scatter(x, y2, marker='o', c='darkgreen', label='买') ax.scatter(x, y3, marker='o', c='firebrick', label='卖') # 一些小设置 # 设置 x 轴显示密度 tick_spacing = 8 ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing)) # 设置 x 坐标轴标签的显示内容和大小 plt.xlabel('时间', fontsize=16) # 设置 x 坐标轴刻度的旋转方向和大小 plt.xticks(rotation=90, fontsize=16) # 设置 y 坐标轴刻度大小 plt.yticks(fontsize=18) # 坐标轴中文显示 plt.rcParams['font.sans-serif'] = ['SimHei'] # 调整图的位置 plt.subplots_adjust(top=0.9, bottom=0.22) # 设置尺寸 fig.set_size_inches(24, 12) # po_annotation1 为 ‘买’ 时需要显示的标注信息 # 该 list 内部存放多个子 list,每个子 list 为 [标注点的坐标, 标注] po_annotation1 = [] for i in range(len(x)): # 标注点的坐标 point_x = x[i] point_y = y2[i] point, = plt.plot(point_x, point_y, 'o', c='darkgreen') # 标注框偏移量 offset1 = 80 offset2 = 80 # 标注框 bbox1 = dict(boxstyle="round", fc='lightgreen', alpha=0.6) # 标注箭头 arrowprops1 = dict(arrowstyle="->", connectionstyle="arc3,rad=0.") # 标注 annotation = plt.annotate(text1[i], xy=(x[i], y2[i]), xytext=(-offset1, offset2), textcoords='offset points', bbox=bbox1, arrowprops=arrowprops1, size=15) # 默认鼠标未指向时不显示标注信息 annotation.set_visible(False) po_annotation1.append([point, annotation]) po_annotation2 = [] for i in range(len(x)): # 标注点的坐标: point_x = x[i] point_y = y3[i] point, = plt.plot(point_x, point_y, 'o', c='firebrick') # 标注框偏移量 offset1 = 30 offset2 = 80 # 标注框 bbox2 = dict(boxstyle="round", fc='salmon', alpha=0.6) # 标注箭头 arrowprops2 = dict(arrowstyle="->", connectionstyle="arc3,rad=0.") # 标注 annotation = plt.annotate(text2[i], xy=(x[i], y3[i]), xytext=(-offset1, offset2), textcoords='offset points', bbox=bbox2, arrowprops=arrowprops2, size=15) # 默认鼠标未指向时不显示标注信息 annotation.set_visible(False) po_annotation2.append([point, annotation]) # 定义鼠标响应函数 def on_move(event): visibility_changed = False for point, annotation in po_annotation1: should_be_visible = (point.contains(event)[0] == True) if should_be_visible != annotation.get_visible(): visibility_changed = True annotation.set_visible(should_be_visible) for point, annotation in po_annotation2: should_be_visible = (point.contains(event)[0] == True) if should_be_visible != annotation.get_visible(): visibility_changed = True annotation.set_visible(should_be_visible) if visibility_changed: plt.draw() # 鼠标移动事件 on_move_id = fig.canvas.mpl_connect('motion_notify_event', on_move) plt.show() 效果

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3