多坐标轴场景下如何让标注bbox置于所有图层上方?
问题:Matplotlib标注bbox被线条覆盖的解决方法
给定以下代码:
from pandas import DataFrame, date_range, Timestamp from numpy import arange data = DataFrame({'A': arange(100, 200), 'B': arange(500, 400, -1)}, index=date_range('2024-01-01', periods=100)) ax_a = data['A'].plot(color='C0') ax_b = data['B'].plot(color='C1', secondary_y=True) ax_a.annotate( '', (Timestamp('2024-01-15'), 120), xytext=(Timestamp('2024-03-20'), 120), arrowprops=dict(arrowstyle="->", color='C0', ), ) ax_a.annotate(f'Label A', (Timestamp('2024-03-02'), 120), bbox=dict(fc="0.8")) ax_b.annotate( '', (Timestamp('2024-03-20'), 420), xytext=(Timestamp('2024-01-15'), 420), arrowprops=dict(arrowstyle="->", color='C1', ), ) ax_b.annotate(f'Label B', (Timestamp('2024-02-02'), 420), bbox=dict(fc="0.8"))
运行后,ax_b上的线条会覆盖“Label A”的bbox,需要修改哪里才能让所有线条(包括标注箭头)都不重叠标注bbox及其内容?
解决方案:调整元素绘制层级(zorder)
Matplotlib的元素绘制顺序由zorder参数控制,值越大的元素越晚绘制,会覆盖在低层元素之上。默认情况下折线和箭头的层级高于标注文本,因此会出现覆盖问题。只需调整各元素的zorder值即可解决:
- 给折线图设置较低的
zorder(如1),让线条处于底层 - 给标注箭头设置和线条相同的
zorder,避免箭头覆盖标注 - 给标注文本及bbox设置较高的
zorder(如10),确保它们处于顶层
修改后的代码
from pandas import DataFrame, date_range, Timestamp from numpy import arange data = DataFrame({'A': arange(100, 200), 'B': arange(500, 400, -1)}, index=date_range('2024-01-01', periods=100)) # 折线设置底层zorder ax_a = data['A'].plot(color='C0', zorder=1) ax_b = data['B'].plot(color='C1', secondary_y=True, zorder=1) # 箭头和折线同层级 ax_a.annotate( '', (Timestamp('2024-01-15'), 120), xytext=(Timestamp('2024-03-20'), 120), arrowprops=dict(arrowstyle="->", color='C0', zorder=1), ) # 标注文本和bbox设置顶层zorder ax_a.annotate(f'Label A', (Timestamp('2024-03-02'), 120), bbox=dict(fc="0.8"), zorder=10) ax_b.annotate( '', (Timestamp('2024-03-20'), 420), xytext=(Timestamp('2024-01-15'), 420), arrowprops=dict(arrowstyle="->", color='C1', zorder=1), ) ax_b.annotate(f'Label B', (Timestamp('2024-02-02'), 420), bbox=dict(fc="0.8"), zorder=10)
这样修改后,所有标注的bbox和文本都会显示在折线和箭头之上,不会被覆盖。
内容的提问来源于stack exchange,提问作者Chris Withers
相关产品推荐
相关产品推荐

