有一个很好的通用方法来获取数据坐标中任意matplotlib Artist的边界框吗?

ali*_*i_m 5 python transformation matplotlib

如果有一种通用的方法来获取任意matplotlib艺术家的数据坐标中的边界框,我会发现它非常有用.

例如:

from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle, Ellipse
import numpy as np

fig, ax = plt.subplots(1, 1)

r = Rectangle((0, 1), 3, 2, color='r')
e = Ellipse((1, 0), 4, 2, 30, color='g')
l = plt.plot(np.r_[1, 2, 0, 3, 2], c='b', lw=2)[0]

ax.add_patch(r)
ax.add_patch(e)

ax.set_xlim(-2, 5)
ax.set_ylim(-2, 4)
Run Code Online (Sandbox Code Playgroud)

获取矩形的边界框非常简单 - 我可以使用它的get_bbox()方法:

print(r.get_bbox())
# [ 0.  1.  3.  3.]
Run Code Online (Sandbox Code Playgroud)

但是,线和椭圆都没有get_bbox()方法.对于线路,似乎我可以这样做:

print(l.get_path().get_extents().extents)
# [ 0.  0.  4.  3.]
Run Code Online (Sandbox Code Playgroud)

但相应的方法给我一个不正确的椭圆结果:

print(e.get_path().get_extents().extents)
# [-1. -1.  1.  1.]
Run Code Online (Sandbox Code Playgroud)

到目前为止我发现的最好的"通用"方法是基于这个答案,并用于get_window_extent()获取显示空间中的边界框,然后使用逆轴数据转换转换回数据坐标:

def get_bbox_generic(a):
    fig, ax = a.figure, a.axes
    disp = a.get_window_extent(renderer=fig.canvas.renderer)
    return disp.transformed(ax.transData.inverted())
Run Code Online (Sandbox Code Playgroud)

然而,这种方法至少有一些缺点:它将失败,除非先前已经渲染过图形,并且变换后的坐标有点不精确.

有没有更好的办法?