diff --git a/doc/api/next_api_changes/behavior/30183-TS.rst b/doc/api/next_api_changes/behavior/30183-TS.rst new file mode 100644 index 000000000000..9aad35a278f3 --- /dev/null +++ b/doc/api/next_api_changes/behavior/30183-TS.rst @@ -0,0 +1,3 @@ +savefig() pad_inches per-border specification +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +pad_inches will now accept a 4-tuple specifying the padding per border, in the order [left, right, bottom, top]. \ No newline at end of file diff --git a/doc/users/next_whats_new/pad_inches_per_border.rst b/doc/users/next_whats_new/pad_inches_per_border.rst new file mode 100644 index 000000000000..f74f0e5001b7 --- /dev/null +++ b/doc/users/next_whats_new/pad_inches_per_border.rst @@ -0,0 +1,4 @@ +savefig() pad_inches per-border specification +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +pad_inches will now accept a 4-tuple specifying the padding per border, in the order [left, right, bottom, top]. This can be used to simply and precisely modify the bounding box of what in a figure is saved to a file. \ No newline at end of file diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 527d8c010710..5f54b71edae0 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2088,11 +2088,11 @@ def print_figure( Bounding box in inches: only the given portion of the figure is saved. If 'tight', try to figure out the tight bbox of the figure. - pad_inches : float or 'layout', default: :rc:`savefig.pad_inches` - Amount of padding in inches around the figure when bbox_inches is - 'tight'. If 'layout' use the padding from the constrained or - compressed layout engine; ignored if one of those engines is not in - use. + pad_inches : float, 4-tuple of floats, or 'layout', + default: :rc:`savefig.pad_inches`. Amount of padding in inches + around the figure when bbox_inches is 'tight'. If 'layout' use the + padding from the constrained or compressed layout engine; ignored + if one of those engines is not in use. bbox_extra_artists : list of `~matplotlib.artist.Artist`, optional A list of extra artists that will be considered when the @@ -2161,13 +2161,20 @@ def print_figure( renderer, bbox_extra_artists=bbox_extra_artists) if (isinstance(layout_engine, ConstrainedLayoutEngine) and pad_inches == "layout"): - h_pad = layout_engine.get()["h_pad"] - w_pad = layout_engine.get()["w_pad"] + b_pad = t_pad = layout_engine.get()["h_pad"] + l_pad = r_pad = layout_engine.get()["w_pad"] else: - if pad_inches in [None, "layout"]: + if isinstance(pad_inches, (int, float)): + l_pad = r_pad = b_pad = t_pad = pad_inches + elif pad_inches in [None, "layout"]: pad_inches = rcParams['savefig.pad_inches'] - h_pad = w_pad = pad_inches - bbox_inches = bbox_inches.padded(w_pad, h_pad) + l_pad = r_pad = b_pad = t_pad = pad_inches + else: + l_pad = pad_inches[0] + r_pad = pad_inches[1] + b_pad = pad_inches[2] + t_pad = pad_inches[3] + bbox_inches = bbox_inches.padded_4sides(l_pad, r_pad, b_pad, t_pad) # call adjust_bbox to save only the given area restore_bbox = _tight_bbox.adjust_bbox( diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index c15da7597acd..3d9a46421a92 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -3409,11 +3409,11 @@ def savefig(self, fname, *, transparent=None, **kwargs): Bounding box in inches: only the given portion of the figure is saved. If 'tight', try to figure out the tight bbox of the figure. - pad_inches : float or 'layout', default: :rc:`savefig.pad_inches` - Amount of padding in inches around the figure when bbox_inches is - 'tight'. If 'layout' use the padding from the constrained or - compressed layout engine; ignored if one of those engines is not in - use. + pad_inches : float, 4-tuple of floats, or 'layout', + default: :rc:`savefig.pad_inches`. Amount of padding in inches + around the figure when bbox_inches is 'tight'. If 'layout' use the + padding from the constrained or compressed layout engine; ignored + if one of those engines is not in use. facecolor : :mpltype:`color` or 'auto', default: :rc:`savefig.facecolor` The facecolor of the figure. If 'auto', use the current figure diff --git a/lib/matplotlib/transforms.py b/lib/matplotlib/transforms.py index 7228f05bcf9e..2a55047a9a60 100644 --- a/lib/matplotlib/transforms.py +++ b/lib/matplotlib/transforms.py @@ -613,6 +613,14 @@ def padded(self, w_pad, h_pad=None): h_pad = w_pad return Bbox(points + [[-w_pad, -h_pad], [w_pad, h_pad]]) + def padded_4sides(self, l, r, b, t): + """ + Construct a `Bbox` by padding this one by a possibly different + amount on each side. + """ + points = self.get_points() + return Bbox(points + [[-l, -b], [r, t]]) + def translated(self, tx, ty): """Construct a `Bbox` by translating this one by *tx* and *ty*.""" return Bbox(self._points + (tx, ty))