如何实现数据标签默认隐藏,鼠标悬停蜡烛图时显示?
实现K线图鼠标悬停显示数据标签的方案
下面提供两种实现思路,分别是基于原生Matplotlib手动处理事件,以及使用mplfinance快速实现:
方法一:原生Matplotlib手动实现悬停提示
这种方式适合需要高度自定义交互逻辑的场景:
import matplotlib.pyplot as plt import numpy as np # 模拟K线数据 dates = np.arange('2024-01-01', '2024-01-10', dtype='datetime64[D]') opens = np.random.randint(100, 120, size=9) highs = opens + np.random.randint(1, 5, size=9) lows = opens - np.random.randint(1, 5, size=9) closes = np.random.randint(lows, highs, size=9) # 创建画布和坐标轴 fig, ax = plt.subplots(figsize=(10, 6)) # 绘制K线实体和影线 width = 0.5 for i in range(len(dates)): # 绘制K线实体 rect_y = min(opens[i], closes[i]) rect_height = abs(closes[i] - opens[i]) rect = plt.Rectangle( (i - width/2, rect_y), width, rect_height, color='red' if closes[i] < opens[i] else 'green' ) ax.add_patch(rect) # 绘制上下影线 plt.plot([i, i], [lows[i], highs[i]], color='black') # 设置坐标轴标签和标题 ax.set_xticks(range(len(dates))) ax.set_xticklabels(dates.astype(str), rotation=45) ax.set_xlabel('日期') ax.set_ylabel('价格') ax.set_title('K线图鼠标悬停数据提示') # 创建初始隐藏的注释框 annot = ax.annotate( '', xy=(0,0), xytext=(20,20), textcoords='offset points', bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.8), arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0') ) annot.set_visible(False) def update_annotation(x_pos): # 将鼠标x坐标转换为K线索引 idx = int(np.round(x_pos)) if idx < 0 or idx >= len(dates): annot.set_visible(False) return # 获取当前K线的所有数据 current_date = dates[idx].astype(str) o, h, l, c = opens[idx], highs[idx], lows[idx], closes[idx] # 更新注释框的位置和内容 annot.xy = (idx, c) annot_text = f'日期: {current_date}\n开盘价: {o}\n最高价: {h}\n最低价: {l}\n收盘价: {c}' annot.set_text(annot_text) def on_mouse_move(event): if event.inaxes == ax: update_annotation(event.xdata) annot.set_visible(True) fig.canvas.draw_idle() else: if annot.get_visible(): annot.set_visible(False) fig.canvas.draw_idle() # 绑定鼠标移动事件 fig.canvas.mpl_connect('motion_notify_event', on_mouse_move) plt.tight_layout() plt.show()
关键细节说明:
- 使用
ax.annotate()替代axes.text():注释框支持动态隐藏/显示,还能添加箭头指向目标K线,视觉效果更清晰。 - 坐标转换:通过鼠标事件的
xdata直接获取图表内的x坐标,转换为K线索引,无需复杂的屏幕坐标计算。 - 边界处理:添加索引越界判断,避免鼠标移出K线区域时出现错误。
方法二:使用mplfinance快速实现
如果你使用mplfinance库绘制K线,可以直接开启内置的悬停提示,无需手动处理事件:
import mplfinance as mpf import pandas as pd import numpy as np # 模拟K线数据 dates = np.arange('2024-01-01', '2024-01-10', dtype='datetime64[D]') data = pd.DataFrame({ 'Open': np.random.randint(100, 120, size=9), 'High': np.random.randint(120, 125, size=9), 'Low': np.random.randint(95, 100, size=9), 'Close': np.random.randint(95, 125, size=9) }, index=dates) # 绘制K线并开启悬停提示 mpf.plot( data, type='candle', style='yahoo', tooltip=True, # 开启悬停提示 title='K线图内置悬停提示' )
额外提示:
- 自定义样式:手动实现时,可以通过修改
annot的bbox参数调整提示框的背景色、圆角,fontsize调整文本大小。 - 性能优化:如果K线数据量极大(比如数千条),可以在
on_mouse_move中添加节流逻辑,减少更新频率。 - 多坐标轴适配:如果图表包含成交量等子图,需要在事件处理中判断鼠标所在的坐标轴,避免误触发。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

