Skip to content

Deprecated tight_bbox and tight_layout modules #22134

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

Merged
merged 2 commits into from
Jan 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/api/next_api_changes/deprecations/22134-OG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Modules ``tight_bbox`` and ``tight_layout`` deprecated
------------------------------------------------------

The modules ``matplotlib.tight_bbox`` and ``matplotlib.tight_layout`` are
considered internal and public access is deprecated.
6 changes: 3 additions & 3 deletions doc/api/prev_api_changes/api_changes_1.4.x.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ original location:
``drawRect`` from ``FigureCanvasQTAgg``; they were always an
implementation detail of the (preserved) ``drawRectangle()`` function.

* The function signatures of `.tight_bbox.adjust_bbox` and
`.tight_bbox.process_figure_for_rasterizing` have been changed. A new
*fixed_dpi* parameter allows for overriding the ``figure.dpi`` setting
* The function signatures of ``matplotlib.tight_bbox.adjust_bbox`` and
``matplotlib.tight_bbox.process_figure_for_rasterizing`` have been changed.
A new *fixed_dpi* parameter allows for overriding the ``figure.dpi`` setting
instead of trying to deduce the intended behaviour from the file format.

* Added support for horizontal/vertical axes padding to
Expand Down
2 changes: 1 addition & 1 deletion doc/api/prev_api_changes/api_changes_2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ If `.MovieWriterRegistry` can't find the requested `.MovieWriter`, a
more helpful `RuntimeError` message is now raised instead of the
previously raised `KeyError`.

`~.tight_layout.auto_adjust_subplotpars` now raises `ValueError`
``matplotlib.tight_layout.auto_adjust_subplotpars`` now raises `ValueError`
instead of `RuntimeError` when sizes of input lists don't match


Expand Down
8 changes: 4 additions & 4 deletions doc/api/prev_api_changes/api_changes_3.0.1.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
API Changes for 3.0.1
=====================

`.tight_layout.auto_adjust_subplotpars` can return ``None`` now if the new
subplotparams will collapse axes to zero width or height. This prevents
``tight_layout`` from being executed. Similarly
`.tight_layout.get_tight_layout_figure` will return None.
``matplotlib.tight_layout.auto_adjust_subplotpars`` can return ``None`` now if
the new subplotparams will collapse axes to zero width or height.
This prevents ``tight_layout`` from being executed. Similarly
``matplotlib.tight_layout.get_tight_layout_figure`` will return None.

To improve import (startup) time, private modules are now imported lazily.
These modules are no longer available at these locations:
Expand Down
85 changes: 85 additions & 0 deletions lib/matplotlib/_tight_bbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""
Helper module for the *bbox_inches* parameter in `.Figure.savefig`.
"""

from matplotlib.transforms import Bbox, TransformedBbox, Affine2D


def adjust_bbox(fig, bbox_inches, fixed_dpi=None):
"""
Temporarily adjust the figure so that only the specified area
(bbox_inches) is saved.

It modifies fig.bbox, fig.bbox_inches,
fig.transFigure._boxout, and fig.patch. While the figure size
changes, the scale of the original figure is conserved. A
function which restores the original values are returned.
"""
origBbox = fig.bbox
origBboxInches = fig.bbox_inches
orig_tight_layout = fig.get_tight_layout()
_boxout = fig.transFigure._boxout

fig.set_tight_layout(False)

old_aspect = []
locator_list = []
sentinel = object()
for ax in fig.axes:
locator_list.append(ax.get_axes_locator())
current_pos = ax.get_position(original=False).frozen()
ax.set_axes_locator(lambda a, r, _pos=current_pos: _pos)
# override the method that enforces the aspect ratio on the Axes
if 'apply_aspect' in ax.__dict__:
old_aspect.append(ax.apply_aspect)
else:
old_aspect.append(sentinel)
ax.apply_aspect = lambda pos=None: None

def restore_bbox():
for ax, loc, aspect in zip(fig.axes, locator_list, old_aspect):
ax.set_axes_locator(loc)
if aspect is sentinel:
# delete our no-op function which un-hides the original method
del ax.apply_aspect
else:
ax.apply_aspect = aspect

fig.bbox = origBbox
fig.bbox_inches = origBboxInches
fig.set_tight_layout(orig_tight_layout)
fig.transFigure._boxout = _boxout
fig.transFigure.invalidate()
fig.patch.set_bounds(0, 0, 1, 1)

if fixed_dpi is None:
fixed_dpi = fig.dpi
tr = Affine2D().scale(fixed_dpi)
dpi_scale = fixed_dpi / fig.dpi

fig.bbox_inches = Bbox.from_bounds(0, 0, *bbox_inches.size)
x0, y0 = tr.transform(bbox_inches.p0)
w1, h1 = fig.bbox.size * dpi_scale
fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0, w1, h1)
fig.transFigure.invalidate()

fig.bbox = TransformedBbox(fig.bbox_inches, tr)

fig.patch.set_bounds(x0 / w1, y0 / h1,
fig.bbox.width / w1, fig.bbox.height / h1)

return restore_bbox


def process_figure_for_rasterizing(fig, bbox_inches_restore, fixed_dpi=None):
"""
A function that needs to be called when figure dpi changes during the
drawing (e.g., rasterizing). It recovers the bbox and re-adjust it with
the new dpi.
"""

bbox_inches, restore_bbox = bbox_inches_restore
restore_bbox()
r = adjust_bbox(fig, bbox_inches, fixed_dpi)

return bbox_inches, r
Loading