Matplotlib坐标转换

8

我正在尝试理解这段代码片段:

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)

这段代码为现有图像添加了一个插入框,如下所示:enter image description here 原始代码来自于这个笔记本文件
我不明白为什么需要两次坐标变换:
inax_position = ax.transAxes.transform(rect[0:2])
infig_position = ax.figure.transFigure.inverted().transform(inax_position)
1个回答

10

说明

在方法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])

阅读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()

输入图像描述


我可以将逻辑总结如下:将插图(A)添加到现有轴(B)中需要在图形(C)中插入一个新的轴。插图的位置通常相对于B的坐标定义,因此为了向C添加A,我们需要将A的坐标从B的空间转换为显示坐标,然后再转换回C的坐标。我的理解正确吗? - Cheng
一个后续问题,也许是个愚蠢的问题,为什么我不能直接从坐标轴坐标系转换到图形坐标系?为什么需要在两者之间进行从坐标轴到显示器的转换? - Cheng
这不是一个愚蠢的问题。Matplotlib提供了transDatatransAxestransFigure转换,可以直接使用。虽然没有提供从轴到图形的转换,但可以很容易地从两个现有的转换中生成它。我已经编辑了答案,并添加了两行代码来说明它的实现方式。 - ImportanceOfBeingErnest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接