【问题标题】:Embedding small plots inside subplots in matplotlib在 matplotlib 的子图中嵌入小图
【发布时间】:2013-07-01 18:26:06
【问题描述】:

如果你想在一个更大的图中插入一个小图,你可以使用Axes,比如here。

问题是我不知道如何在子图中做同样的事情。

我有几个子图,我想在每个子图中绘制一个小图。 示例代码将是这样的:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()

for i in range(4):
    ax = fig.add_subplot(2,2,i)
    ax.plot(np.arange(11),np.arange(11),'b')

    #b = ax.axes([0.7,0.7,0.2,0.2]) 
    #it gives an error, AxesSubplot is not callable

    #b = plt.axes([0.7,0.7,0.2,0.2])
    #plt.plot(np.arange(3),np.arange(3)+11,'g')
    #it plots the small plot in the selected position of the whole figure, not inside the subplot

有什么想法吗?

提前致谢!

【问题讨论】:

  • 正在研究解决方案,我发现另一个问题...stackoverflow.com/questions/17478165/…
  • 非常感谢你们两位。正如比尔建议的那样,我可以使用 AxesGrid 中的 zoomed_inset_axis 以及 Pablo 的功能来完成我正在寻找的事情。最后,我使用了 Pablo 的函数,因为它比 AxesGrid 更舒适地在所有子图中绘制所有具有相同大小的小图形。再次感谢!

标签: matplotlib plot embedding axes subplot


【解决方案1】:

我写了一个与 plt.axes 非常相似的函数。你可以用它来绘制你的子子图。有一个例子……

import matplotlib.pyplot as plt
import numpy as np

#def add_subplot_axes(ax,rect,facecolor='w'): # matplotlib 2.0+
def add_subplot_axes(ax,rect,axisbg='w'):
    fig = plt.gcf()
    box = ax.get_position()
    width = box.width
    height = box.height
    inax_position  = ax.transAxes.transform(rect[0:2])
    transFigure = fig.transFigure.inverted()
    infig_position = transFigure.transform(inax_position)    
    x = infig_position[0]
    y = infig_position[1]
    width *= rect[2]
    height *= rect[3]  # <= Typo was here
    #subax = fig.add_axes([x,y,width,height],facecolor=facecolor)  # matplotlib 2.0+
    subax = fig.add_axes([x,y,width,height],axisbg=axisbg)
    x_labelsize = subax.get_xticklabels()[0].get_size()
    y_labelsize = subax.get_yticklabels()[0].get_size()
    x_labelsize *= rect[2]**0.5
    y_labelsize *= rect[3]**0.5
    subax.xaxis.set_tick_params(labelsize=x_labelsize)
    subax.yaxis.set_tick_params(labelsize=y_labelsize)
    return subax
    
def example1():
    fig = plt.figure(figsize=(10,10))
    ax = fig.add_subplot(111)
    rect = [0.2,0.2,0.7,0.7]
    ax1 = add_subplot_axes(ax,rect)
    ax2 = add_subplot_axes(ax1,rect)
    ax3 = add_subplot_axes(ax2,rect)
    plt.show()

def example2():
    fig = plt.figure(figsize=(10,10))
    axes = []
    subpos = [0.2,0.6,0.3,0.3]
    x = np.linspace(-np.pi,np.pi)
    for i in range(4):
        axes.append(fig.add_subplot(2,2,i))
    for axis in axes:
        axis.set_xlim(-np.pi,np.pi)
        axis.set_ylim(-1,3)
        axis.plot(x,np.sin(x))
        subax1 = add_subplot_axes(axis,subpos)
        subax2 = add_subplot_axes(subax1,subpos)
        subax1.plot(x,np.sin(x))
        subax2.plot(x,np.sin(x))
if __name__ == '__main__':
    example2()
    plt.show()

【讨论】:

    【解决方案2】:

    您现在可以使用 matplotlibs inset_axes 方法执行此操作(请参阅 docs):

    from mpl_toolkits.axes_grid.inset_locator import inset_axes
    inset_axes = inset_axes(parent_axes,
                        width="30%", # width = 30% of parent_bbox
                        height=1., # height : 1 inch
                        loc=3)
    

    更新:正如Kuti 指出的,对于matplotlib 2.1 或更高版本,您应该将import 语句更改为:

    from mpl_toolkits.axes_grid1.inset_locator import inset_axes
    

    现在还有一个full example 显示所有可用的不同选项。

    【讨论】:

    【解决方案3】:

    从matplotlib 3.0开始,你可以使用matplotlib.axes.Axes.inset_axes:

    import numpy as np
    import matplotlib.pyplot as plt
    
    fig, axes = plt.subplots(2,2)
    
    for ax in axes.flat:
        ax.plot(np.arange(11),np.arange(11))
    
        ins = ax.inset_axes([0.7,0.7,0.2,0.2])
    
    plt.show()
    

    与@jrieke's answer 中提到的mpl_toolkits.axes_grid.inset_locator.inset_axes 的不同之处在于它更易于使用(没有额外的导入等),但缺点是灵活性稍差(没有填充或角位置的参数)。

    【讨论】:

      【解决方案4】:

      来源:https://matplotlib.org/examples/pylab_examples/axes_demo.html

      from mpl_toolkits.axes_grid.inset_locator import inset_axes
      import matplotlib.pyplot as plt
      import numpy as np
      
      # create some data to use for the plot
      dt = 0.001
      t = np.arange(0.0, 10.0, dt)
      r = np.exp(-t[:1000]/0.05)               # impulse response
      x = np.random.randn(len(t))
      s = np.convolve(x, r)[:len(x)]*dt  # colored noise
      
      fig = plt.figure(figsize=(9, 4),facecolor='white')
      ax = fig.add_subplot(121)
      # the main axes is subplot(111) by default
      plt.plot(t, s)
      plt.axis([0, 1, 1.1*np.amin(s), 2*np.amax(s)])
      plt.xlabel('time (s)')
      plt.ylabel('current (nA)')
      plt.title('Subplot 1: \n Gaussian colored noise')
      
      # this is an inset axes over the main axes
      inset_axes = inset_axes(ax, 
                          width="50%", # width = 30% of parent_bbox
                          height=1.0, # height : 1 inch
                          loc=1)
      n, bins, patches = plt.hist(s, 400, normed=1)
      #plt.title('Probability')
      plt.xticks([])
      plt.yticks([])
      
      ax = fig.add_subplot(122)
      # the main axes is subplot(111) by default
      plt.plot(t, s)
      plt.axis([0, 1, 1.1*np.amin(s), 2*np.amax(s)])
      plt.xlabel('time (s)')
      plt.ylabel('current (nA)')
      plt.title('Subplot 2: \n Gaussian colored noise')
      
      plt.tight_layout()
      plt.show()
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 2015-07-15
      • 2015-02-17
      • 1970-01-01
      • 2018-06-14
      • 2019-04-08
      相关资源
      最近更新 更多