Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tight(er) whitespace around figure when saving #101

Merged
merged 2 commits into from Aug 10, 2022

Conversation

pnkraemer
Copy link
Owner

@pnkraemer pnkraemer commented Aug 10, 2022

Resolves #100. When saving a figure via (e.g.) plt.savefig, there tends to be more whitespace around the figure than desired. This PR removes almost all whitespace. The rationale is that when embedding the figure into a paper/pdf, the paper-layout should handle the whitespace, not the figure itself.

Before:
before.pdf

After:
after.pdf

The padding value of 0.015 inches is a little ad-hoc (I personally found 0.01 too small and 0.02 too large, but 馃し), and quite aggressive (removes almost all whitespace). But the value is exposed to users, and can therefore be changed easily.

@pnkraemer pnkraemer merged commit 5a5306d into main Aug 10, 2022
@pnkraemer pnkraemer deleted the whitespace-around-figures branch August 10, 2022 12:36
@daskol
Copy link

daskol commented Jan 4, 2024

I'm afraid that this issue introduced a regression: resulting media size differs from declared one.

import matplotlib as mpl
import matplotlib.pyplot as plt

def save_fig(what: str, rc: dict):
    with mpl.rc_context(rc):
        fig, ax = plt.subplots(figsize=(3.25, 2.01), layout='constrained')
        ax.plot([i ** 2 for i in range(10)], '-..', label=r'$x^2$')
        ax.legend()
        ax.set_xlabel(r'$x$')
        ax.set_ylabel(r'$f(x)$')
        fig.savefig(f'{what}.pdf')
        fig.savefig(f'{what}.png')
        fig.savefig(f'{what}.svg')

save_fig('standard', {'savefig.bbox': 'standard', 'savefig.pad_inches': 0.015})
save_fig('tight', {'savefig.bbox': 'tight', 'savefig.pad_inches': 0.015})

Then we get images with different size in pixels while DPI is the same and equals to 100.

$ file *.png
standard.png: PNG image data, 325 x 200, 8-bit/color RGBA, non-interlaced
tight.png:    PNG image data, 319 x 195, 8-bit/color RGBA, non-interlaced

Bounding boxes of generated PDFs differs too.

$ echo {standard,tight}.pdf | xargs -n1 pdfinfo | grep -i 'page size'       
Page size:       234 x 144.72 pts
Page size:       230.16 x 140.88 pts

From my perspective matplotlib documentation is a little bit vague and unclear at this point but it seems that savefig.bbox/bbox_inches tweak somehow shape of bounding box of Artist's on Figure and use it instead of bounding box of original canvas.

UPD I don't know what figsize and dpi was in your sample abut sizes of generated PDFs follow.

$ echo {before,after}.pdf | xargs -n1 pdfinfo | grep -i 'page size'
Page size:       494.4 x 158.582 pts
Page size:       482.16 x 146.342 pts

@pnkraemer
Copy link
Owner Author

I opened an issue based on your comment. Let's figure out a solution there :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Whitespace around figures when saving
2 participants