Matplotlib图表对象层级调整:如何让线条置于最上层
问题
我用Matplotlib绘制了包含多种元素的图表,想把线条放在所有元素最上层(或自定义显示层级),但用zorder参数没达到预期效果,相关代码如下:
fig10, ax = plt.subplots(figsize=(24,12)) plt.rcParams['font.size'] = '12' plt.rcParams["axes.edgecolor"] = "black" plt.rcParams["axes.linewidth"] = 2 ax.set_title('MW66: Soggiacenza falda vs Spessore Prodotto', fontsize=18,fontweight="bold") ax.plot(periodo, assey1, '-o', color="navy", linewidth = 3,label = 'Soggiacenza Falda [m da b.p.]',zorder=1) ax.set_facecolor("#ffffff") ax.set_xlabel('', fontsize=18) ax.set_ylabel('Soggiacenza Falda [m da b.p.]', color="black", fontsize=15) ax.set_axisbelow(True) ax.grid() #ax.set_xlim(periodo.min() - timedelta(days=2), periodo.max() + timedelta(days=2)) ax.set_xlim([date(2022, 9, 23), today+ timedelta(days=2)]) #datetime.date(2021, 1, 8)] ax.xaxis.set_major_locator(mdates.DayLocator(interval=7)) #ax.xaxis.set_minor_locator(mdates.WeekdayLocator(interval=1)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d")) plt.xticks(rotation = 45) ax.axvline(dt.datetime(2023, 1, 30),linewidth=2, color='black') ax.axvline(dt.datetime(2023, 3, 27),linewidth=2, color='fuchsia') #ax.axvline(dt.datetime(2023, 1, 30),linewidth=2, color='lime') ax.text(dt.datetime(2023, 1, 27), 6.55, 'Pompa Pneumatica', rotation='vertical',color='black',fontweight="bold",fontsize=18) ax.text(dt.datetime(2023, 3, 24), 6.55 , 'Elettropompa Sommersa - P&T', rotation='vertical',color='fuchsia',fontweight="bold",fontsize=18) #ax.text(dt.datetime(2022, 11, 19), 6.9, 'Sommersa', rotation='vertical',color='fuchsia',fontweight="bold",fontsize=18) #ax.text(dt.datetime(2023, 1, 27), 5.75, 'Avvio P&T', rotation='vertical',color='lime',fontweight="bold",fontsize=18) ax.set_ylim(7,4) ax.set_axisbelow(True) plt.gcf().autofmt_xdate() ## Asse Secondario ax2=ax.twinx() ax2.plot(periodo2, assey2_spess, color="orange",linewidth = 3,label = 'Spessore Prodotto [m]',zorder=1) #ax2.bar(periodo2, assey2_spess,width = 0.8, color = 'Orange', alpha=0.8,label = 'Spessore Prodotto [m]') #ax2.axhline(CSC, color = 'red', linestyle = '--',linewidth = 3, label = 'CSC', alpha= 0.75) ax2.set_ylabel('Spessore Prodotto [m]',color="black",fontsize=18,rotation=90) ax2.set_ylim(0,0.5) plt.fill_between(periodo2, 0, assey2_spess, lw=0, color='orange', alpha= 0.75,zorder=3) lines, labels = ax.get_legend_handles_labels() lines2, labels2 = ax2.get_legend_handles_labels() ax2.legend(lines + lines2, labels + labels2, bbox_to_anchor=(0.45, -0.08),ncol=3, frameon=False, loc='upper center',fontsize=15) fig10.tight_layout()
解决建议
- 调整
zorder数值优先级:当前线条的zorder=1,而填充区域fill_between设为zorder=3,Matplotlib中数值越大显示层级越高,所以填充会盖在线条上。把需要置顶的线条zorder设为更高值,比如给ax.plot和ax2.plot设zorder=10,填充区域设zorder=2,确保线条层级最高。 - 注意孪生轴的层级独立性:
ax2是ax的孪生轴,两个轴的元素渲染是独立的。如果ax的线条被ax2的元素遮挡,要确保ax线条的zorder足够高,或者降低ax2元素的zorder。另外axvline默认zorder=2,如果需要调整它的层级,也要显式设置zorder参数。 - 优化绘制顺序:Matplotlib默认按代码执行顺序渲染元素,后绘制的元素会叠加在上方。如果调整
zorder仍有问题,可以把需要置顶的线条移到所有其他元素(填充、竖线、文本等)之后绘制。 - 清理冗余设置:代码中两次调用
ax.set_axisbelow(True),该设置仅用于将网格和轴线放在绘图元素下方,重复调用无意义,保留一次即可。
内容的提问来源于stack exchange,提问作者Stefano Alberti
相关产品推荐
相关产品推荐

