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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't fallback to agg in tight_layout.get_renderer. #15221

Merged
merged 1 commit into from
May 26, 2020

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Sep 8, 2019

tight_layout.get_renderer currently falls back to agg if it is unable to
get a renderer for the current canvas, but we actually have a way to
coerce the canvas to produce a renderer, via
backend_bases._get_renderer.

This renderer gets used by the tight_layout machinery to estimate text
size. Falling back to Agg would produce bad results in the (admittedly
rare) cases where text size estimation yields very different results
depending on the renderer -- the easiest way to trigger this is to use
a "thin" font, e.g. Tex Gyre Chorus, while using the pdf backend with
the "pdf.use14corefonts" rcParam set to True, which effectively forces
Helvetica. e.g.

from pylab import *
matplotlib.use("pdf")
rcdefaults()
rcParams.update({"pdf.use14corefonts": True, "font.family": "TeX Gyre Chorus"})
plot()
margins(0)
tight_layout(0)
savefig("/tmp/test.pdf")

would crop the tick labels before this PR.

(The real point is not to fix an obscure edge case, but actually to have
fewer places that fall back to Agg as "favorited" backend.)

PR Summary

PR Checklist

  • Has Pytest style unit tests
  • Code is Flake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

try:
print_method(io.BytesIO())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dpi was many other things than figure.dpi in my quick skim of the code below, so is it really OK to use figure.dpi here? I'll block because I think this should be answered, but anyone should clear if this is really not a problem. I haven't looked carefully yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If _get_renderer is called from print_figure(), then figure.dpi has already been set to match the requested savefig dpi (cbook._setattr_cm(self.figure, dpi=dpi)), so setting it a second time is a noop. If called from tight_layout.get_renderer, OTOH, we do need to pass in the figure dpi -- otherwise it's savefig.dpi which gets used, which is not correct when we want to tight-layout something not for the purpose of saving it.

@tacaswell
Copy link
Member

I don't think this rebase went correctly...

@tacaswell tacaswell added this to the v3.3.0 milestone Apr 1, 2020
@anntzer
Copy link
Contributor Author

anntzer commented Apr 2, 2020

fixed the rebase

@anntzer
Copy link
Contributor Author

anntzer commented Apr 22, 2020

As an aside, this closes #1852, I think.

@QuLogic
Copy link
Member

QuLogic commented May 9, 2020

This seems to break the output from #9158.

@QuLogic
Copy link
Member

QuLogic commented May 9, 2020

Ah no wait, it's just because this branch is outdated and EPS was broken for some time, but fixed on master.

@anntzer
Copy link
Contributor Author

anntzer commented May 9, 2020

I'm a bit confused: what's broken? (if anything?)

@QuLogic
Copy link
Member

QuLogic commented May 11, 2020

Nothing. The bug is fixed on master and unrelated; it's only here because it was based on an old commit.

@jklymak
Copy link
Member

jklymak commented May 26, 2020

Codecov is not thrilled with this. Is it humanly possible to make tests for this?

tight_layout.get_renderer currently falls back to agg if it is unable to
get a renderer for the current canvas, but we actually have a way to
coerce the canvas to produce a renderer, via
backend_bases._get_renderer.

This renderer gets used by the tight_layout machinery to estimate text
size.  Falling back to Agg would produce bad results in the (admittedly
rare) cases where text size estimation yields very different results
depending on the renderer -- the easiest way to trigger this is to use
a "thin" font, e.g. Tex Gyre Chorus, while using the pdf backend with
the "pdf.use14corefonts" rcParam set to True, which effectively forces
Helvetica. e.g.
```
from pylab import *
matplotlib.use("pdf")
rcdefaults()
rcParams.update({"pdf.use14corefonts": True, "font.family": "TeX Gyre Chorus"})
plot()
margins(0)
tight_layout(0)
savefig("/tmp/test.pdf")
```
would crop the tick labels before this PR.

(The real point is not to fix an obscure edge case, but actually to have
fewer places that fall back to Agg as "favorited" backend.)
@anntzer
Copy link
Contributor Author

anntzer commented May 26, 2020

added a test.

@QuLogic QuLogic merged commit 9ccdb1d into matplotlib:master May 26, 2020
@anntzer anntzer deleted the get_renderer branch May 26, 2020 21:10
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.

5 participants