Matplotlib 坐标变换

Che*_*eng 8 python matplotlib

我试图理解这个代码片段:

def add_inset(ax, rect, *args, **kwargs):
    box = ax.get_position()
    inax_position = ax.transAxes.transform(rect[0:2])
    infig_position = ax.figure.transFigure.inverted().transform(inax_position)
    new_rect = list(infig_position) + [box.width * rect[2], box.height * rect[3]]
    return fig.add_axes(new_rect, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

此代码向现有图形添加插图。它看起来像这样: 在此处输入图片说明

原始代码来自这个 notebook 文件。

我不明白为什么需要两个坐标转换:

inax_position = ax.transAxes.transform(rect[0:2])
infig_position = ax.figure.transFigure.inverted().transform(inax_position)
Run Code Online (Sandbox Code Playgroud)

Imp*_*est 8

解释

在方法中add_inset(ax, rect),rect是轴坐标中的矩形。这是有道理的,因为您通常希望指定相对于其所在轴的插入位置。
但是,为了以后能够创建新轴,需要在图形坐标中知道轴位置,然后可以将其提供给fig.add_axes(figurecoordinates)。所以需要的是从轴坐标到图形坐标的坐标变换。此处分两步执行此操作:

  1. 从轴坐标转换到显示坐标使用 transAxes。
  2. 使用 的倒数从显示坐标转换为图形坐标transFigure。

这两个步骤的过程可以进一步浓缩在一个单一的变换中

mytrans = ax.transAxes + ax.figure.transFigure.inverted()
infig_position = mytrans.transform(rect[0:2])
Run Code Online (Sandbox Code Playgroud)

阅读matplotlib转换教程可能会有兴趣如何工作。

备择方案

以上可能不是放置插图的最明显方法。Matplotlib 本身提供了一些工具。一种方便的方法是mpl_toolkits.axes_grid1.inset_locator. 以下是inset_axes在轴坐标中创建插图时使用其方法的两种方法。

import matplotlib.pyplot as plt
import mpl_toolkits.axes_grid1.inset_locator as il

fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(4,4))
ax1.plot([1,2,3],[2.2,2,3])

# set the inset at upper left (loc=2) with width, height=0.5,0.4
axins = il.inset_axes(ax1, "50%", "40%", loc=2, borderpad=1)
axins.scatter([1,2,3],[3,2,3])

# set the inset at 0.2,0.5, with width, height=0.8,0.4 
#   in parent axes coordinates
axins2 = il.inset_axes(ax2, "100%", "100%", loc=3, borderpad=0,
    bbox_to_anchor=(0.2,0.5,0.7,0.4),bbox_transform=ax2.transAxes,)
axins2.scatter([1,2,3],[3,2,3])

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明