Skip to content


tight_bbox made assumptions about the display-units without checking the figure #1138

wants to merge 1 commit into from

2 participants


This PR tries to fix #1135. Tight_bbox tries to determine the bounding box of figure contents and saves a new figure that is shrunk to the new size. When saving a PDF using the PGF backend (which internally uses display-units) the scaling is wrong.

For rescaling the figure, adjust_bbox_pdf does some strange unit conversions I do not understand while adjust_bbox_png just uses the scaling matrix from the figure. Using fig.dpi_scale_trans works just fine for the PGF, PDF, SVG and EPS backend, so I removed the adjust_bbox_pdf function altogether.

There are no tests for bbox_inches and I don't really understand what bbox_inches is doing, so this needs some review.

Matplotlib Developers member

I do not remember the details why I had two separate functions, but obviously there was cases where "adjust_bbox_png" does not work for pdf, ps and svg backend. Unfortunately, I cannot remember which were those cases. I thought rasterization were involved, but my simple test seem to suggest that "adjust_bbox_png" also work with rasterization.

However, as a original author of the "tight_bbox" option, I am a little hesitant in accepting this PR as there may still exist some cases where "adjust_bbox_png" does not work as expected.

I believe another solution for this is to set the figure dpi to 72 before saving as pgf. This is what pdf backend does and I think this was main reason why we had "adjust_bbox_png" as a separate function.
So, for consistency, I think we should change the dpi to 72 before saving as pgf (or at least for saving pdf w/ pgf backend). And I think this will solve the tight_bbox issue on pgf backend as a side-effect.

So, my proposal is,

for 1.2, we set the figure dpi to 72 before saving as pgf

and after 1.2 is out,

we get rid of "adjust_bbox_pdf" in the dev branch and see if everything works.


But isn't the dpi an essential setting the user might want to control? Savefig.dpi affects the resolution of images embedded in the figures, why should a backend override this?

Matplotlib Developers member

In the default pdf backend, the original Figure.dpi value is saved as image_dpi before overriding the Figure.dpi, and the renderer uses image_dpi for the resolution of images (ps backend behaves similarly). I am not in a position to tell why this is implemented this way.

Still, it could be a bug of tight_bbox-related routines. And looking at the code, "adjust_bbox_pdf" does not make much sense to me and I do not remember why this is made so unfortunately. This could have been my oversight, or this could have something to do with rasterizaition as it (temporarily) changes the figure dpi.

What I am suggesting is that we try to fix this after 1.2 is released.


All right, I'm closing this PR in favor of a temporary workaround for PGF:

Is it possible that the tight_bbox functionality pre-dates the tight_layout function? They are very similar, but implemented in completely different ways. For example, the sole purpose of the first fake saving process in bbox_inches=='tight' is to get hands on a renderer instance. Tight_layout does this by just simply calling get_renderer from the backend. Both implementations now try to determine the sizes of all figure elements for the given canvas. After that, tight_bbox creates smaller figure and tight_layout makes the plot fill the figsize. This is essentially the functionality a single unified layout manager should take care of.

@pwuertz pwuertz closed this
Matplotlib Developers member

Yes, the tight_bbox functionality pre-dates the tight_layout function. While they are very similar, but they are implemented (slightly) differently as they expect different side-effect. bbox_inches="tight" does not change the location of artists in the figure, but tight_layout does. tight_layout is intended for interactive use, thus it assume that figure is already drawn. This cannot be assumed for bbox_inches="tight". Of course, it will be good to have a layout manager for matplotlib!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 23, 2012
This page is out of date. Refresh to see the latest.
Showing with 4 additions and 30 deletions.
  1. +4 −30 lib/matplotlib/
34 lib/matplotlib/
@@ -57,7 +57,7 @@ def restore_bbox():
return None
-def adjust_bbox_png(fig, bbox_inches):
+def _adjust_bbox(fig, bbox_inches):
adjust_bbox for png (Agg) format
@@ -83,31 +83,6 @@ def adjust_bbox_png(fig, bbox_inches):
fig.bbox.width/w1, fig.bbox.height/h1)
-def adjust_bbox_pdf(fig, bbox_inches):
- """
- adjust_bbox for pdf & eps format
- """
- tr = Affine2D().scale(72)
- _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
- f = 72. / fig.dpi
- w1, h1 = fig.bbox.width*f, fig.bbox.height*f
- 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)
def process_figure_for_rasterizing(figure,
bbox_inches_restore, mode):
@@ -126,7 +101,6 @@ def process_figure_for_rasterizing(figure,
_adjust_bbox_handler_d = {}
-for format in ["png", "raw", "rgba", "jpg", "jpeg", "tiff"]:
- _adjust_bbox_handler_d[format] = adjust_bbox_png
-for format in ["pdf", "eps", "svg", "svgz"]:
- _adjust_bbox_handler_d[format] = adjust_bbox_pdf
+for format in ["png", "raw", "rgba", "jpg", "jpeg", "tiff",
+ "pdf", "eps", "svg", "svgz"]:
+ _adjust_bbox_handler_d[format] = _adjust_bbox
Something went wrong with that request. Please try again.