-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ENH: Allow tuple for borderpad in AnchoredOffsetbox #30359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
ENH: Allow tuple for borderpad in AnchoredOffsetbox #30359
Conversation
98cfadf
to
8df4614
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Aaratrika-Shelly, nice work! I have confirmed this solves the inset_axes
issue:
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig, ax = plt.subplots()
axins = inset_axes(ax, width="30%", height=1., loc="upper left", borderpad=(3, 0))
plt.show()

Please could you update the inset_axes docstring to match what you have done here? This should also get a what's new entry and "added" directive.
8df4614
to
c84ef64
Compare
All the suggested changes have been made. Thanks for the suggestions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Aaratrika-Shelly, this will still need a new entry in https://github.com/matplotlib/matplotlib/tree/main/doc/users/next_whats_new
Also I just remembered that the type annotation will need updating in offsetbox.pyi. We do not yet have typing stubs for anything under toolkits
so there is nothing to do for type annotations for inset_axes
.
ax.add_artist(text_tuple_equal) | ||
|
||
# Case 3: Test that an asymmetric tuple with larger values works as expected. | ||
text_tuple_asym = AnchoredText("tuple_asym", loc='lower left', borderpad=(10, 15)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest making one of these less than 5. At the moment the below assertions would pass even if only one element of the tuple mistakenly got used for both x and y.
@@ -1053,13 +1055,22 @@ def set_bbox_to_anchor(self, bbox, transform=None): | |||
|
|||
@_compat_get_offset | |||
def get_offset(self, bbox, renderer): | |||
# docstring inherited |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring for this method is still inherited from the parent class, so this comment should not be removed.
lib/matplotlib/offsetbox.py
Outdated
fontsize_in_pixels = renderer.points_to_pixels(self.prop.get_size_in_points()) | ||
try: | ||
borderpad_x, borderpad_y = self.borderpad | ||
except (TypeError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
except (TypeError): | |
except TypeError: |
Brackets are not needed if we only catch one exception.
lib/matplotlib/offsetbox.py
Outdated
def _get_anchored_bbox(loc, bbox, parentbbox, pad_x,pad_y=None): | ||
""" | ||
Return the (x, y) position of the *bbox* anchored at the *parentbbox* with | ||
the *loc* code with the *borderpad*. | ||
""" | ||
# This is only called internally and *loc* should already have been | ||
# validated. If 0 (None), we just let ``bbox.anchored`` raise. | ||
c = [None, "NE", "NW", "SW", "SE", "E", "W", "E", "S", "N", "C"][loc] | ||
container = parentbbox.padded(-borderpad) | ||
if pad_y is None: | ||
pad_y=pad_x | ||
container = parentbbox.padded(-pad_x,-pad_y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def _get_anchored_bbox(loc, bbox, parentbbox, pad_x,pad_y=None): | |
""" | |
Return the (x, y) position of the *bbox* anchored at the *parentbbox* with | |
the *loc* code with the *borderpad*. | |
""" | |
# This is only called internally and *loc* should already have been | |
# validated. If 0 (None), we just let ``bbox.anchored`` raise. | |
c = [None, "NE", "NW", "SW", "SE", "E", "W", "E", "S", "N", "C"][loc] | |
container = parentbbox.padded(-borderpad) | |
if pad_y is None: | |
pad_y=pad_x | |
container = parentbbox.padded(-pad_x,-pad_y) | |
def _get_anchored_bbox(loc, bbox, parentbbox, pad_x, pad_y=None): | |
""" | |
Return the (x, y) position of the *bbox* anchored at the *parentbbox* with | |
the *loc* code with the *borderpad*. | |
""" | |
# This is only called internally and *loc* should already have been | |
# validated. If 0 (None), we just let ``bbox.anchored`` raise. | |
c = [None, "NE", "NW", "SW", "SE", "E", "W", "E", "S", "N", "C"][loc] | |
if pad_y is None: | |
pad_y = pad_x | |
container = parentbbox.padded(-pad_x, -pad_y) |
Spaces after commas and around the equals sign. The linter should have picked these up - I'm not sure why it didn't.
versionchanged:: 3.11 | ||
The *borderpad* parameter now accepts a tuple of (x, y) paddings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be versionadded
because you are introducing a new option but the old option still works. Also it should go under the parameter description. For a similar example see
matplotlib/lib/matplotlib/stackplot.py
Lines 67 to 68 in 011d12f
.. versionadded:: 3.9 | |
Support for list input |
c84ef64
to
2b60116
Compare
This PR closes #30331 .
PR summary
This PR enhances
AnchoredOffsetbox
to allow theborderpad
parameter to accept a tuple of(x_pad, y_pad)
in addition to a single float value.Why is this change necessary? Currently,
borderpad
applies the same padding in both x and y directions. This can be inflexible, especially when placing inset axes in a corner. For example, a user may want horizontal padding to avoid overlapping the main plot's y-axis labels, but no vertical padding in order to keep the inset flush with the top of the plot area.What problem does it solve? It gives users finer control over the positioning of anchored elements, allowing for separate horizontal and vertical padding.
What is the reasoning for this implementation?
AnchoredOffsetbox.get_offset
.self.borderpad
is a tuple and calculates separatepad_x_pixels
andpad_y_pixels
.A new unit test has been added to verify this functionality, and the docstring for
AnchoredOffsetbox
has been updated to reflect the new API.PR checklist