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
相关产品推荐
相关产品推荐

