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

如何让matplotlib中mark_inset连线在图例下方、刻度标记在折线图上方?

解决方案

问题1:调整mark_inset连线至图例下方

mark_inset函数会返回连线和主图上的矩形框两个元素,只需将它们的zorder设为低于图例的zorder即可。同时注意正确获取图例对象(原代码中链式调用set_zorder会导致变量为None):

# 修改图例创建代码,拆分赋值与zorder设置
leg = ax.legend(handlelength=0, handletextpad=0, fontsize=8, fancybox=1, 
                framealpha=1, labelcolor='linecolor', loc='lower center')
leg.set_zorder(15)

# 修改mark_inset部分,捕获返回元素并设置zorder
inset_lines, inset_rect = mark_inset(ax, ax2, loc1=2, loc2=3, fc='none', ec='k', lw=0.8)
for line in inset_lines:
    line.set_zorder(7)  # 低于图例的15
inset_rect.set_zorder(7)

问题2:将刻度标记置于折线图上方

在tick_params中添加zorder参数,设置为大于折线的zorder值(折线zorder为4-6,这里设为10即可),确保刻度线和标签显示在折线之上:

# 主图刻度设置
ax.tick_params(axis="both", which='both', labelsize=9, 
            direction='in', left=True, bottom=True, right=True, top=True,
            zorder=10)

# 子图刻度设置
ax2.tick_params(axis="both", which='both', labelsize=9,
            direction='in', left=True, bottom=True, right=True, top=True,
            zorder=10)

修改后的完整代码

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1.inset_locator import InsetPosition, mark_inset

plind = 1 # don't want the first plot
### make the main plot
fig, ax = plt.subplots(1, 1, figsize=(3.35,2.5), dpi=150)
### make the first plot
### three bits of data
ax.plot(f[plind:]/1e3, s[plind:], zorder=4, c='C0', label='BES')
ax.plot(ff[plind:]/1e3, ss[plind:], zorder=6, c='C2', label='BES welch, N=2$^3$')
ax.plot(fbeam[plind:]/1e3, sbeam[plind:], lw=0.8, zorder=5, c='C1', label='Beam')
### want this fill between on the right
ax.fill_between([5e2,4e3], [ylim[0],ylim[0]], [ylim[-1],ylim[-1]], color='C3', alpha=0.3, zorder=3)
### set the x and y limits
ax.set_xlim([4e-3, 2e3])
ax.set_ylim([1e-19, 1e-1])
### want it in log scale
ax.set_xscale('log')
ax.set_yscale('log')
### set the ylabel
ax.set_ylabel('Spectra (V$^2$/Hz)', fontsize=9)
### formatting the ticks - 添加zorder参数
ax.tick_params(axis="both", which='both', labelsize=9, 
            direction='in', left=True, bottom=True, right=True, top=True,
            zorder=10)
ax.minorticks_on()
### make the legend - 拆分赋值与zorder设置
leg = ax.legend(handlelength=0, handletextpad=0, fontsize=8, fancybox=1, 
                framealpha=1, labelcolor='linecolor', loc='lower center')
leg.set_zorder(15)
### changing the positions so it fits within my box
X0 = ax.get_position().x0 + 0.07
X1 = ax.get_position().x1 - 0.32
Y0 = ax.get_position().y0 + 0.06
Y1 = ax.get_position().y1 + 0.09
ax.set_position([X0, Y0, X1-X0, Y1-Y0])

### making the inset
ax2 = plt.axes([0, 0, 1, 1])
ip = InsetPosition(ax, [1.05, 0., 1, 1])
ax2.set_axes_locator(ip)
# 捕获mark_inset返回元素并设置zorder
inset_lines, inset_rect = mark_inset(ax, ax2, loc1=2, loc2=3, fc='none', ec='k', lw=0.8)
for line in inset_lines:
    line.set_zorder(7)
inset_rect.set_zorder(7)

### plot the data again
ax2.plot(f[plind:]/1e3, s[plind:], zorder=4, c='C0')
ax2.plot(ff[plind:]/1e3, ss[plind:], zorder=6, c='C2')
ax2.plot(fbeam[plind:]/1e3, sbeam[plind:], lw=0.8, zorder=5, c='C1')
### limit it and set the log scale for y only
ax2.set_xlim([2, 7])
ax2.set_ylim([5e-12,2e-5])
ax2.set_yscale('log')
### format the ticks - 添加zorder参数
ax2.yaxis.tick_right()
ax2.tick_params(axis="both", which='both', labelsize=9,
            direction='in', left=True, bottom=True, right=True, top=True,
            zorder=10)
ax2.minorticks_on()
ax2.set_xticks(np.arange(2,7.1,1))

### make a joint axis for the xlabel
ax3=fig.add_subplot(111, frameon=False)
ax3.set_position([ax.get_position().x0, ax.get_position().y0,
                  ax2.get_position().x1-ax.get_position().x0,
                  ax.get_position().y1-ax.get_position().y0])
ax3.tick_params(labelcolor='none', which='both', top=False, bottom=False, left=False, right=False)
ax3.set_xlabel('Frequency (kHz)')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 23:18:19