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

Matplotlib中Hover Tooltip无法覆盖图表标题的技术问询

解决Matplotlib图例悬停Tooltip被标题覆盖的问题

这个问题的核心原因是:你当前的Tooltip是创建在**Axes(子图)层面的元素,而图表的主标题(suptitle)和副标题(fig.text)是直接属于Figure(画布)**层面的元素。在Matplotlib的绘制层级中,Figure层面的元素默认会覆盖Axes层面的元素——哪怕你给Axes里的Tooltip设置了很高的zorder也没用,因为这两个层级的zorder是分开计算的。

要让Tooltip始终处于最顶层,我们需要把Tooltip也改成Figure层面的元素,并且给它设置一个足够高的zorder,确保能覆盖所有Figure层面的文本。

修改后的完整代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import matplotlib
print("matplotlib.__version__ {}".format(matplotlib.__version__))
import matplotlib.pyplot as plt
import numpy as np

def onhover(event, fig, axes, leg, tooltip):
    if leg.get_window_extent().contains(event.x,event.y):
        hoveredtxt = None
        for itxt in leg.get_texts():
            if itxt.get_window_extent().contains(event.x,event.y):
                hoveredtxt = itxt
                break
        if hoveredtxt is not None:
            ttxt = "'{}' is hovered!".format(hoveredtxt.get_text())
            tttxt = "\n".join( [ttxt, ttxt, ttxt] )
            tooltip.set_text( tttxt )
            tooltip.set_visible(True)
            tooltip.set_transform( None )  # 使用屏幕坐标定位
            tooltip.set_position( (event.x, event.y) )
        else:
            tooltip.set_visible(False)
    fig.canvas.draw_idle()

def main():
    xdata = np.arange(0, 101, 1) # 0 to 100, both included
    ydata1 = np.sin(0.01*xdata*np.pi/2)
    ydata2 = 10*np.sin(0.01*xdata*np.pi/4)
    fig, ax1 = plt.subplots(1, 1, figsize=(9, 6), dpi=120)
    fig.subplots_adjust(hspace=0)
    pl11, = ax1.plot(xdata, ydata1, color="Red", label="My plot")
    pl12, = ax1.plot(xdata, ydata2, color="Blue", label="Other stuff")
    leg = ax1.legend(ncol=2, bbox_to_anchor=(0,1.01), loc="lower left", borderaxespad=0, prop={'size': 8})
    
    # 关键修改:将Tooltip创建为Figure层面的文本,设置高zorder确保顶层显示
    tooltip = fig.text(0, 0, 'TEST', 
                      bbox=dict(boxstyle="round", facecolor="LightGray", alpha=1), 
                      zorder=1000, fontsize=8)
    tooltip.set_visible(False)
    
    fig.suptitle("Here is some comparison of data", fontsize=10)
    fig.text(0.5, 0.938, "and here is a 'subtitle' for the comparison", fontsize=8, ha='center')
    fig.canvas.mpl_connect('motion_notify_event', lambda event: onhover(event, fig, (ax1,), leg, tooltip ))
    plt.show()

# ENTRY POINT
if __name__ == '__main__':
    main()

核心修改点说明

  • Tooltip归属层级调整:将原来的ax1.text()改为fig.text(),让Tooltip成为Figure的直接子元素,这样它的zorder就能和标题等Figure元素处于同一个层级竞争。
  • zorder设置:保持zorder=1000这个足够高的值,确保它能覆盖默认zorder较低的标题元素(Matplotlib中Figure文本的默认zorder一般在10左右)。

这样修改后,当你悬停图例时,Tooltip会完全覆盖标题和其他所有元素,背景完全不透明,文本清晰可见。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:59:50