It would be very useful for me if there was a general way to get bounding fields in data coordinates for any arbitrary matplotlib artist.
For instance:
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)
Getting the bounding box of a rectangle is very simple - I can just use its get_bbox() method:
print(r.get_bbox())
However, neither the line nor the ellipse have the get_bbox() method. For the line, it seems that I can do:
print(l.get_path().get_extents().extents) # [ 0. 0. 4. 3.]
but the corresponding method gives me the wrong result for an ellipse:
print(e.get_path().get_extents().extents) # [-1. -1. 1. 1.]
The best “general” method I have found so far is based on this answer and uses get_window_extent() to get the bounding rectangle in the display space, then converting the inverse axis data to convert back to data coordinates:
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())
However, this approach has at least several drawbacks: it will fail if the visualization has not been previously shown, and the transformed coordinates are a little inaccurate.
Is there a better way?