Matplotlib中如何让内嵌子图共享主图的轴样式?
如何让Matplotlib内嵌子图共享主图的轴样式?
我想要创建一个带有内嵌子图(inset figure)的图形,但内嵌子图并未共享主图的样式属性,如何强制内嵌子图共享主图的轴样式?
以下是我使用的代码:
def initializeFigure(xlabel, ylabel, scale= 'loglog',width='1col', height=None): import matplotlib as mpl from matplotlib import pyplot as plt # make sure defaults are used plt.style.use(['science', 'scatter']) plt.rcParams['text.usetex'] = True import matplotlib # Prepare figure width and height cm_to_inch = 0.393701 # [inch/cm] # Get figure width in inch if width == '1col': width = 8.8 # width [cm] elif width == '2col': width = 18.0 # width [cm] figWidth = width * cm_to_inch # width [inch] # Get figure height in inch if height is None: fig_aspect_ratio = 7.5/10. figHeight = figWidth * fig_aspect_ratio # height [inch] else: figHeight = height * cm_to_inch # height [inch] # Create figure with right resolution for publication fig = plt.figure(figsize=(figWidth, figHeight), dpi=300) # Add axis object and select as current axis for pyplot ax = fig.add_subplot(111) plt.sca(ax) ax.tick_params(axis='both', which='minor',left=0,right=0,bottom=0, top=0, direction='out', labelsize='medium', pad=2) ax.tick_params(axis='both', which='major',left=1,right=0,bottom=1, top=0, direction='out', labelsize='small', pad=2) if scale=='loglog': # ax.loglog(x,y, label =label) ax.set_yscale('log') ax.set_xscale('log') elif scale=='semilogy': ax.set_yscale('log') elif scale=='semilogx': ax.set_xscale('log') else: pass ax.set_ylabel(xlabel) ax.set_xlabel(ylabel) return fig, ax ylabel =r'$p(\delta \ell)$' xlabel = r'$\delta \ell~[d_{i}]$' fig, ax= initializeFigure(ylabel, xlabel,'2col') plt.loglog(np.logspace(np.log10(1), np.log10(100), 1000), 1/np.logspace(np.log10(1), np.log10(100), 1000)) axins2 = ax.inset_axes([0.02, 0.02, 0.42, 0.42]) axins2.yaxis.set_label_position("right") axins2.xaxis.set_label_position("top") axins2.yaxis.tick_right() x, y = np.random.rand(100),np.random.rand(100) axins2.plot(x, y )
解决方案
方法1:手动复制主图轴样式参数
内嵌子图不会自动继承主图的tick_params等自定义样式,直接将主图的轴配置参数复制给内嵌子图即可:
在创建axins2后,添加以下代码:
# 复制主图的major tick参数 axins2.tick_params(axis='both', which='major', **ax.tick_params(which='major')) # 复制主图的minor tick参数 axins2.tick_params(axis='both', which='minor', **ax.tick_params(which='minor'))
若需同步更多属性(如刻度方向、标签大小),可直接提取主图属性赋值:
# 同步刻度方向 axins2.tick_params(direction=ax.tick_params()['direction']) # 同步标签大小 axins2.tick_params(labelsize=ax.tick_params()['labelsize'])
方法2:封装样式配置函数
将轴样式配置逻辑封装为独立函数,主图和内嵌子图均可调用该函数应用相同样式,避免重复代码:
- 添加样式配置函数:
def configure_axis_style(ax): ax.tick_params(axis='both', which='minor',left=0,right=0,bottom=0, top=0, direction='out', labelsize='medium', pad=2) ax.tick_params(axis='both', which='major',left=1,right=0,bottom=1, top=0, direction='out', labelsize='small', pad=2)
- 在
initializeFigure函数中替换原ax.tick_params代码,调用该函数:
configure_axis_style(ax)
- 创建内嵌子图后,同样调用该函数:
axins2 = ax.inset_axes([0.02, 0.02, 0.42, 0.42]) configure_axis_style(axins2) # 保留内嵌子图的自定义轴位置设置 axins2.yaxis.set_label_position("right") axins2.xaxis.set_label_position("top") axins2.yaxis.tick_right()
方法3:通过rcParams全局统一配置
若希望所有轴(包括内嵌子图)自动应用相同样式,可将刻度配置添加到rcParams中,所有新建轴都会继承这些样式:
在initializeFigure函数的样式设置部分,添加以下代码:
plt.rcParams['xtick.direction'] = 'out' plt.rcParams['ytick.direction'] = 'out' plt.rcParams['xtick.major.size'] = 4 plt.rcParams['ytick.major.size'] = 4 plt.rcParams['xtick.minor.size'] = 0 plt.rcParams['ytick.minor.size'] = 0 plt.rcParams['xtick.labelsize'] = 'small' plt.rcParams['ytick.labelsize'] = 'small' # 按需添加其他统一样式参数
这样无需单独配置主图或内嵌子图,所有轴都会自动应用预设样式。
内容的提问来源于stack exchange,提问作者Jokerp
相关产品推荐
相关产品推荐

