-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
tight_layout relies on get_renderer, which is not available on all backends #1852
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
Comments
I noticed this too. It also happens with the PDF backend: $ python
Python 2.7.3 (default, Nov 29 2012, 11:01:29)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib
>>> matplotlib.use('pdf')
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> ax = fig.add_subplot(1, 1, 1)
>>> fig.tight_layout()
/Users/damon/python/lib/matplotlib-1.3.x-py2.7-macosx-10.8-x86_64.egg/matplotlib/tight_layout.py:225: UserWarning: tight_layout : falling back to Agg renderer
warnings.warn("tight_layout : falling back to Agg renderer") We could move from using the renderer directly to updating the |
I agree with @dmcdougall: I think that's what needs to be done. It has the added benefit of making |
@mdehoon , @dmcdougall : Just to clarify, tight_layout still works without error (only warning)? Or does it raise an exception? The only reason that we need a renderer instance is to calculate the size and location of texts. @mdehoon, is this something impossible outside the event loop? I am not quite clear about the suggestion by @dmcdougall. Does it mean that we call |
tight_layout still works, but it works by falling back to the Agg renderer, which should not be necessary. To calculate the size of texts, I presume you will need to call renderer.get_text_width_height_descent (either directly or indirectly). But renderer.get_text_width_height_descent needs a graphics context to be able to do its job, and it can only get a (properly initialized) graphics context from inside the callback in the event loop. This callback calls fig.draw, so I think @dmcdougall 's suggestion is to reorganize the tight_layout code such that the calculations are done as part of fig.draw. |
We have As far as I can see, we need to access renderer at the time when |
@leejjoon The method In [1]: import matplotlib
In [2]: matplotlib.use('pdf')
In [3]: import matplotlib.pyplot as plt
In [4]: fig = plt.figure()
In [5]: ax = fig.add_subplot(1,1,1)
In [6]: fig.set_tight_layout(True)
In [7]: fig.savefig('asd.pdf') # No warning now @mdehoon I'm on a linux box at the moment, would you be able to try this on OS X? If this works on Mac, could we add |
@dmcdougall : fig.set_tight_layout seems to work fine with the MacOSX backend. Also if I replace fig.add_subplot by plt.subplot, then the set_tight_layout works fine, both in interactive and in non-interactive mode. So it looks like set_tight_layout is working fine. I have no idea why fig.add_subplot does nothing while plt.subplot works fine, but anyway this is independent of set_tight_layout. |
@dmcdougall It turned out that the difference between fig.add_subplot and plt.subplot is due to the fact that the latter includes a call to draw_if_interactive while the former doesn't. If I add plt.draw_if_interactive() to your example, fig.set_tight_layout works fine with the MacOSX backend both in interactive and in non-interactive mode. |
@mdehoon Yeah, sorry. I rarely use the interactive stuff. My go-to is the PDF or Agg backend. |
@leejjoon @dmcdougall @mdehoon : Thank you to all of you... the |
not sure if this is helpful: for me, calling |
See the following links for more info: matplotlib/matplotlib#2654 matplotlib/matplotlib#1852
FWIW: As @nilsbecker notes,
So, for example, in my code, where I typically encounter 'Agg', 'MacOSX' and the Notebook backend, and since
|
Currently on OSX 10.10, Python 3.3.4, Matplotlib 1.4.0 backend "MacOSX". Calling
The figure is still produced and appears to be fine. The warning also occurs if below is implemented. import matplotlib
matplotlib.use('pdf') |
@c-benko Error is present on my Mac OSX 10.10.1 as well. Python 2.7.9, matplotlib 1.4.0 backend "MacOSX" /Users/myName/anaconda/lib/python2.7/site-packages/matplotlib/tight_layout.py:225: UserWarning: tight_layout : falling back to Agg renderer
warnings.warn("tight_layout : falling back to Agg renderer") Using from matplotlib import pyplot as plt and calling plt.tight_layout()
plt.show |
avoid 'Fall back to Agg renderer' as suggested here matplotlib/matplotlib#1852
avoid 'Fall back to Agg renderer' as suggested here matplotlib/matplotlib#1852
I am seeing this warning while running anything using pycharm and anaconda with python 3.5.2 and matplotlib 1.5.3. I dont see this if I run through the jupyter notebook. |
I'm seeing this with 2.0.0rc1 and the Kivy backend. |
I'm having this issue with SVG backend on Windows + python 3.5.5 + matplotlib 2.1.1 |
- self.fig.set_tight_layout(True) and self.fig.tight_layout() both issue warnings (see matplotlib/matplotlib#1852, https://stackoverflow.com/questions/15455029/python-matplotlib-agg-vs-interactive-plotting-and-tight-layout). Removing the figure title and panel titles produces a figure without a lot of whitespace in the margins, so that's the solution for now.
Bump for PDF backend. |
Closed by #15221, I think. |
With the MacOSX backend and possibly other backends, tight_layout falls back to the Agg backend. For example, demo_tight_layout.py does the following:
$ python -i examples/pylab_examples/demo_tight_layout.py
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib-1.3.x-py2.7-macosx-10.6-intel.egg/matplotlib/tight_layout.py:225: UserWarning: tight_layout : falling back to Agg renderer
warnings.warn("tight_layout : falling back to Agg renderer")
This is the relevant code in tight_layout.py:
Neither backend_template.py nor backend_bases.py implement a get_renderer method, nor do the MacOSX and gtkcairo backend (and possibly other backends).
Even if I were to add a get_renderer method to the canvas in the MacOSX backend, this still fails. The problem is that this code tries to grab a renderer and use it outside of the event loop (i.e., outside of the figure.draw method). Outside of the event loop, the graphics context is not defined, and the code fails as follows:
$ python -i examples/pylab_examples/demo_tight_layout.py
Traceback (most recent call last):
File "examples/pylab_examples/demo_tight_layout.py", line 15, in
plt.tight_layout()
...
RuntimeError: CGContextRef is NULL
I would suggest to restructure the code in tight_layout.py to avoid using the renderer directly.
The text was updated successfully, but these errors were encountered: