Source code for matplotlib.tight_bbox

"""
Helper module for the *bbox_inches* parameter in `.Figure.savefig`.
"""

from matplotlib.transforms import Bbox, TransformedBbox, Affine2D


[docs]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 _bbox = TransformedBbox(bbox_inches, tr) fig.bbox_inches = Bbox.from_bounds(0, 0, bbox_inches.width, bbox_inches.height) x0, y0 = _bbox.x0, _bbox.y0 w1, h1 = fig.bbox.width * dpi_scale, fig.bbox.height * 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
[docs]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