Is there a good general method for getting the bounding box of an arbitrary matplotlib Artist in data coordinates?

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()) # [ 0. 1. 3. 3.] 

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?

+5
source share

All Articles