嵌入轴的具体位置

时间:2017-07-28 17:05:08

标签: python matplotlib graph

我想创建一组轴,以在父组轴的特定位置形成插入。因此,仅在loc=1,2,3中使用参数inset_axes是不合适的,如下所示:

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

但是,我想要接近这一点。答案herehere似乎是比我复杂得多的问题的答案。

所以,问题是我可以在上面的代码中替换一个参数,它允许插入轴在父轴中的自定义位置吗?我尝试使用bbox_to_anchor,但不理解documentation中的规范或行为。具体来说,我试过了:

 inset_axes = inset_axes(parent_axes,
                        width="30%", # width = 30% of parent_bbox
                        height=1., # height : 1 inch
                        bbox_to_anchor=(0.4,0.1))

尝试使插图左侧和底部的锚点分别位于x轴和y轴的40%和10%处。或者,我试图把它放在绝对坐标中:

inset_axes = inset_axes(parent_axes,
                            width="30%", # width = 30% of parent_bbox
                            height=1., # height : 1 inch
                            bbox_to_anchor=(-4,-100))

这些都没有正常工作,并给了我一个我无法解释的警告。

更一般地说,似乎loc在属于matplotlib的许多函数中都是一个非常标准的参数,因此,是否可以在任何地方使用这个问题的一般解决方案?似乎bbox_to_anchor是什么,但我再也无法弄清楚如何正确使用它。

2 个答案:

答案 0 :(得分:6)

您采取的方法原则上是正确的。但是,就像when placing a legendbbox_to_anchor一样,该位置被确定为bbox_to_anchorloc之间的相互作用。上述链接答案中的大多数解释也适用于此。

inset_axes的默认locloc=1(“右上角”)。这意味着如果您指定bbox_to_anchor=(0.4,0.1),那么这些将是右上角的坐标,而不是左下角的坐标。
因此,您需要指定loc=3以使插图的左下角位于(0.4,0.1)

但是,如果不以相对单位("30%")指定宽度和高度,则将边界指定为2元组才有意义。或者换句话说,为了使用相对单位,您需要为bbox_to_anchor使用4元组表示法。

如果在轴单位中指定bbox_to_anchor,则需要再次使用bbox_transform参数,就像解释here的图例一样,并将其设置为ax.transAxes

plt.figure(figsize=(6,3))
ax = plt.subplot(221)
ax.set_title("100%, (0.5,1-0.3,.3,.3)")
ax.plot(xdata, ydata)
axins = inset_axes(ax, width="100%", height="100%", loc='upper left',
                   bbox_to_anchor=(0.5,1-0.3,.3,.3), bbox_transform=ax.transAxes)


ax = plt.subplot(222)
ax.set_title("30%, (0.5,0,1,1)")
ax.plot(xdata, ydata)
axins = inset_axes(ax, width="30%", height="30%", loc='upper left',
                   bbox_to_anchor=(0.5,0,1,1), bbox_transform=ax.transAxes)

enter image description here

在matplotlib页面上找到完整的示例:Inset Locator Demo

另一个选项是使用InsetPosition代替inset_axes并为现有轴提供新位置。 InsetPosition将标准化轴坐标中轴的左下角的x和y坐标以及宽度和高度作为输入。

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import InsetPosition

fig, ax= plt.subplots()

iax = plt.axes([0, 0, 1, 1])
ip = InsetPosition(ax, [0.4, 0.1, 0.3, 0.7]) #posx, posy, width, height
iax.set_axes_locator(ip)

iax.plot([1,2,4])
plt.show()

最后应该提一下,从matplotlib 3.0开始,你可以使用matplotlib.axes.Axes.inset_axes

import matplotlib.pyplot as plt

plt.figure(figsize=(6,3))
ax = plt.subplot(221)
ax.set_title("ax.inset_axes, (0.5,1-0.3,.3,.3)")
ax.plot([0,4], [0,10])
axins = ax.inset_axes((0.5,1-0.3,.3,.3))

plt.show()

结果大致相同,只是mpl_toolkits.axes_grid1.inset_locator.inset_axes允许在轴周围填充(并默认应用它),而Axes.inset_axes没有这种填充。

enter image description here

答案 1 :(得分:2)

使用从ImportanceOfBeingErnest答案和一些建议的链接从像未发行的matplotlib文档the locator demoinset_axes docs,它的还是的我花了一些时间弄清楚所有参数的表现。所以,为了清楚起见,我将在此重复我的理解。我最终使用了:

bbox_ll_x = 0.2
bbox_ll_y = 0
bbox_w = 1
bbox_h = 1
eps = 0.01
inset_axes = inset_axes(parent_axes, 
               height="30%", #height of inset axes as frac of bounding box
               width="70%",  #width of inset axes as frac of bounding box
               bbox_to_anchor=(bbox_ll_x,bbox_ll_y,bbox_w-bbox_ll_x,bbox_h), 
               loc='upper left',
               bbox_transform=parent_axes.transAxes)

parent_axes.add_patch(plt.Rectangle((bbox_ll_x, bbox_ll_y+eps),
               bbox_w-eps-bbox_ll_x, 
               bbox_h-eps, 
               ls="--", 
               ec="c", 
               fc="None",
               transform=parent_axes.transAxes))

bbox_ll_x是父轴坐标中边界框左下角的x位置(即bbox_transform输入的含义)

bbox_ll_y是父轴坐标中边界框左下角的y位置

bbox_w是父轴坐标

中边界框的宽度

bbox_h是父轴坐标

中边界框的高度

eps是一个小数字,用于在绘制矩形边界框时从下轴显示矩形。

我使用add_patch调用来放置一条青色虚线,表示绘制的边界框的内边缘。

对我来说最棘手的部分是意识到heightwidth输入(当指定为百分比时)与边界框大小有关。这就是为什么(如下面的链接和答案中所述),如果以百分比形式指定插入轴的大小,则必须bbox_to_anchor参数指定4元组。如果您将插入轴的大小指定为百分比而提供bbox_wbbox_hmatplotlib如何获得插入的绝对大小?

另一件事是loc参数指定在边界框内锚定插入轴的位置。据我所知,这是该参数的唯一功能。