FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[Bug]: Different behavior of tight_layout and set_tight_layout with matplotlib 3.5.0 on macOS · Issue #21673 · matplotlib/matplotlib · GitHub

Repository navigation

[Bug]: Different behavior of tight_layout and set_tight_layout with matplotlib 3.5.0 on macOS #21673

Description

Bug summary

Since matplotlib 3.5.0, I see a slightly different result when using tight_layout() or set_tight_layout(True) with the macOS backend. These differences do not appear with matplotlib 3.4.3, or in a Debian container.

Code for reproduction

import matplotlib.pyplot as plt
from matplotlib.testing.compare import compare_images


fig1, ax1 = plt.subplots()
fig1.set_tight_layout(True)
fig1.savefig("1.png")

fig2, ax2 = plt.subplots()
fig2.tight_layout()
fig2.savefig("2.png")

assert compare_images("1.png", "2.png", 0) is None

Actual outcome

The comparison fails, and the figures slightly differ on macOS:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    assert compare_images("1.png", "2.png", 0) is None
AssertionError

The difference is rather small: the rightmost x-axis tick label slightly moves.

On Debian the assertion succeeds, and when downgrading to matplotlib 3.4.3 it also succeeds on macOS.

Expected outcome

According to the tight layout guide:

Note that matplotlib.pyplot.tight_layout() will only adjust the subplot params when it is called. In order to perform this adjustment each time the figure is redrawn, you can call fig.set_tight_layout(True), or, equivalently, set rcParams["figure.autolayout"] (default: False) to True.

I expect both figures to be equivalent, as there is nothing else happening after the tight_layout() / set_tight_layout(True) call and before saving.

Additional information

I can only reproduce the behavior on macOS with matplotlib 3.5.0. Earlier versions produce consistent figures, and a Debian container with python:3.9-slim also produces consistent figures with matplotlib 3.4.3.

I came across this while trying to understand differences in figure layout observed between CI running Ubuntu and a local macOS setup, which appeared with matplotlib 3.5.0 when using tight_layout(). These differences disappear with set_tight_layout(True), and I also see consistent behavior with constrained_layout.

While the observed difference in the example above is very small, the differences become slightly larger with more complex setups. This gist shows another figure comparison where the differences are a bit more noticeable (though still small, and hard to see unless flipping back and forth between the images).

When switching the backend to TkAgg (matplotlib.use("TkAgg")), the discrepancy also disappears.

Operating system

macOS 11.5.2

Matplotlib Version

3.5.0

Matplotlib Backend

MacOSX

Python version

Python 3.8.10

Jupyter version

6.4.0

Installation

pip

Activity

timhoffm commented on Nov 18, 2021

Member

Does your Mac have a HiDPI screen? This might be related to HiDPI adaptions such as #18274 or #21365 (not necessarily a full list).

greglucas commented on Nov 18, 2021

Contributor

Both of the examples work on my mac. I am unable to reproduce either of the failures (the included one, or the gist). I'm on Catalina with an intel chip, so another possibility is if you're running on the new M1 chip?

alexander-held commented on Nov 18, 2021

Author

I am seeing this with Big Sur on an Intel MacBook Pro, and yes with HiDPI display.

greglucas commented on Nov 19, 2021

Contributor

I think the macosx is a red herring here and only produces it because you start out with a higher dpi. I can reproduce with Agg in a similar test where we set the figure dpi to 200 right away and then save it with a lower dpi later.
Bisects to: #19126
ping @QuLogic

import matplotlib.pyplot as plt
from matplotlib.testing.compare import compare_images
import matplotlib
matplotlib.use('agg')


fig1, ax1 = plt.subplots()
fig1.dpi = 200
fig1.set_tight_layout(True)
fig1.savefig("1.png")

fig2, ax2 = plt.subplots()
fig2.dpi = 200
fig2.tight_layout()
fig2.savefig("2.png")

assert compare_images("1.png", "2.png", 0) is None

QuLogic commented on Nov 19, 2021

Member

#19126 just makes things properly consistent in how DPI is handled; it was wrong in macosx before. This issue doesn't have to do with that specifically, and is a peril of using tight layout, which is rather fragile to DPI, especially with text.

If you call tight_layout(), then the figure is adjusted using 200 DPI, and saved at 100 DPI using the positions that were calculated that one time. If you call set_tight_layout(True), then it's always on and when saving at 100 DPI, it will re-adjust itself which probably comes out different.

I think we can fix this by making tight_layout always work with the original DPI, ignore the saving DPI. That also fixes the problem you whittled it down to as well, with mixed display/saving DPI.

self-assigned this
on Nov 19, 2021

github-actions commented on Nov 10, 2025

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

added
status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.
on Dec 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.status: inactiveMarked by the “Stale” Github Action

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


    Back | FazBrowse Home | New Git URL