Home > database >  Force inset figure to share axis style of main figure- Matplotlib
Force inset figure to share axis style of main figure- Matplotlib

Time:10-15

I would like to create a figure that has an inset figure. However, the inset does not share the style properties of the main figure. How could I force the inset to share the style properties of the main figure? The code I am using is the following:

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 )

My question is the following:

How could I force the inset to share the style properties of the main figure?

enter image description here

CodePudding user response:

One option is to dive into the implementation details of the Axes class and define a function to return the values properties that you define for the original axes. Then you can use this data to set the same properties on the inset Axes.

An alternative, more feasible approach is to accept two additional parameters in your function (major_tick_params=None, minor_tick_params=None) and define inside the function:

    if major_tick_params is None:
        major_params = {'axis':'both',
                'which':'major',
                'left':1,
                'right':0,
                'bottom':1,
                'top':0,
                'direction':'out',
                'labelsize':'small',
                'pad':2}

    if minor_tick_params is None:
        minor_params = {'axis':'both',
                'which':'minor',
                'left':0,
                'right':0,
                'bottom':0,
                'top':0,
                'direction':'out',
                'labelsize':'medium',
                'pad':2}
                
    ax.tick_params(**major_tick_params)
    ax.tick_params(**minor_tick_params) 

Then you can define the major_tick_params and minor_tick_params before you call the function and reuse it on the inset axes.

ylabel                 =r'$p(\delta \ell)$'
xlabel                 = r'$\delta \ell~[d_{i}]$'

minor_tick_params = {'axis':'both',
                'which':'minor',
                'left':0,
                'right':0,
                'bottom':0,
                'top':0,
                'direction':'out',
                'labelsize':'medium',
                'pad':2}

major_tick_params = {'axis':'both',
                'which':'major',
                'left':1,
                'right':0,
                'bottom':1,
                'top':0,
                'direction':'out',
                'labelsize':'small',
                'pad':2}

fig, ax= initializeFigure(ylabel, xlabel,'2col', major_tick_params=major_tick_params, minor_tick_params=minor_tick_params)

xvals = np.logspace(np.log10(1), np.log10(100), 1000)
ax.plot(xvals, 1/xvals)

ax.set_xscale('log')
ax.set_yscale('log')

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)
axins2.tick_params(**minor_tick_params)
axins2.tick_params(**major_tick_params)

enter image description here

  • Related