在 matplotlib 中的子图中嵌入小图

问题描述 投票:0回答:4

如果你想在大图中插入一个小图,你可以使用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

有什么想法吗?

matplotlib plot embedding axes subplot
4个回答
68
投票

我写了一个与 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()

enter image description here


65
投票

您现在可以使用 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

现在还有一个完整示例显示了所有可用的不同选项。


32
投票

从 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 的回答
中提到的 mpl_toolkits.axes_grid.inset_locator.inset_axes 的区别在于,这更容易使用(无需额外的导入等),但缺点是灵活性稍差(没有填充或角位置的参数)。


17
投票

来源: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()
© www.soinside.com 2019 - 2024. All rights reserved.