You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现双标的K线图鼠标悬停时更新图例数据

解决Finplot双标的鼠标悬停图例更新问题

原代码在双标的K线对比场景中,鼠标悬停时右上角图例无法正常显示数据,核心问题包括未给第二个标的添加时间戳列、索引匹配错误、空数据处理不当。以下是修复后的完整代码及关键说明:

修复后的代码

from pandas_datareader import get_data_yahoo
import finplot as fplt


symbol1, symbol2 = 'GOOG', 'BA'
df1 = get_data_yahoo(symbol1, start='2022-10-01', end='2022-10-30')
df1.rename(str.lower, axis='columns', inplace=True)
df2 = get_data_yahoo(symbol2, start='2022-10-01', end='2022-10-30')
df2.rename(str.lower, axis='columns', inplace=True)

# 为两个标的都添加时间戳列,用于匹配悬停事件的x值
df1['dates'] = df1.index.astype('int64')
df2['dates'] = df2.index.astype('int64')

ax = fplt.create_plot(f'{symbol1} - {symbol2} analysis', maximize=True)
fplt.candlestick_ochl(datasrc=df1[['open', 'close', 'high', 'low']], ax=ax)
pb = fplt.candlestick_ochl(datasrc=df2[['open', 'close', 'high', 'low']], ax=ax)
pb.colors['bull_body'], pb.colors['bear_body'] = '#0f0', '#630'

fplt.legend_fill_color = '#f2f2f2'
fplt.legend_text_color = '#070707'
hover_label = fplt.add_legend('', ax=ax)


def update_legend_text(x, y):
    # 通过时间戳匹配对应行,使用iloc[0]获取单一行数据(避免DataFrame格式)
    row1 = df1.loc[df1.dates == x].iloc[0]
    row2 = df2.loc[df2.dates == x].iloc[0]
    
    # 判断K线涨跌,设置对应颜色
    color1 = '004a00' if row1.open < row1.close else 'a00'
    color2 = '004a00' if row2.open < row2.close else 'a00'
    
    # 格式化价格文本,使用正确的HTML标签
    fmt1 = f'<span style="color:#{color1}">%.6f</span>'
    fmt2 = f'<span style="color:#{color2}">%.6f</span>'
    
    # 拼接图例文本,分隔两个标的数据
    rawtxt = (f'<span style="font-size:13px">%s %s</span> &nbsp; O:{fmt1} C:{fmt1} H:{fmt1} L:{fmt1} '
              '||| '
              f'<span style="font-size:13px">%s %s</span> &nbsp; O:{fmt2} C:{fmt2} H:{fmt2} L:{fmt2}')
    
    # 填充数据到文本模板
    hover_label.setText(rawtxt % (
        symbol1, 'D', row1.open, row1.close, row1.high, row1.low,
        symbol2, 'D', row2.open, row2.close, row2.high, row2.low
    ))


def update_crosshair_text(x, y, xtext, ytext):
    # 交叉线显示当前鼠标位置对应两个标的的收盘价及差值
    close1 = df1.iloc[x].close
    close2 = df2.iloc[x].close
    ytext = (f'%s | {symbol1} C: %.2f (diff%+.2f) | {symbol2} C: %.2f (diff%+.2f)' 
             % (ytext, close1, y - close1, close2, y - close2))
    return xtext, ytext


fplt.set_time_inspector(update_legend_text, ax=ax, when='hover')
fplt.add_crosshair_info(update_crosshair_text, ax=ax)
fplt.autoviewrestore()
fplt.show()

关键修复点说明

  1. 补充时间戳列:为df2添加dates列,确保两个标的都能通过悬停事件的x值(时间戳)匹配到对应行数据。
  2. 修正索引匹配:将原代码中未定义的df.dates分别改为df1.dates和df2.dates,并使用iloc[0]将匹配结果转为Series,避免后续取值报错。
  3. 优化文本渲染:替换原代码中的HTML转义字符为直接可用的HTML标签,确保图例文本正常显示。
  4. 增强交叉线信息:修改update_crosshair_text,同时展示两个标的的收盘价及与鼠标位置的差值,提升交互体验。

内容的提问来源于stack exchange,提问作者AlexStox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 12:25:18