Skip to content

RuntimeError: Cannot get window extent w/o renderer #10874

Closed

Description

@desowin

Bug report

Bug summary

Matplotlib 2.2.0 seems to introduce regression regarding the use of Agg renderer. In specific cases, get_window_extent() does raise RuntimeError: Cannot get window extent w/o renderer.

Code for reproduction

#!/usr/bin/env python3
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111, frameon=True)
ax.plot()

# If the call to draw() below is removed, everything works
# However, this line cases xtick and ytick get_window_extent()
# to raise 'RuntimeError: Cannot get window extent w/o renderer'
# on matplotlib 2.2.0 (tested also on 2.2.2)
#
# Moreover, this works just fine with and without the call to
# draw() below, with matplotlib 2.1.2
plt.get_current_fig_manager().canvas.draw()

ax.set_xlabel(ax.get_xlabel()).get_window_extent()
ax.set_ylabel(ax.get_ylabel()).get_window_extent()
for xtick in ax.get_xticklabels():
    xtick.get_window_extent()
for ytick in ax.get_yticklabels():
    ytick.get_window_extent()

Actual outcome

Traceback (most recent call last):
  File "matplotlib-bug.py", line 22, in <module>
    xtick.get_window_extent()
  File "/usr/lib/python3.6/site-packages/matplotlib/text.py", line 920, in get_window_extent
    raise RuntimeError('Cannot get window extent w/o renderer')
RuntimeError: Cannot get window extent w/o renderer

Expected outcome

No exception should be raised. No exception is raised when the code is used with matplotlib 2.1.2.

Matplotlib version

  • Operating system: Arch Linux
  • Matplotlib version: 2.2.2
  • Matplotlib backend (print(matplotlib.get_backend())): agg
  • Python version: 3.6.4

Installed with pacman -S python python-matplotlib. Tested against older version of matplotlib by installing them in virtualenv using pip.

Activity

  1. desowin commented on Mar 24, 2018

    @desowin
    Author

    The actual problem was noticed in https://bitbucket.org/zunzuncode/zunzunsite3. It manifests itself by the fact that no graphs are not rendered when running with matplotlib 2.2.2. The minimal code to reproduce the reported bug is the result of analyzing the zunzunsite3 code flow, removing all the unnecessary calls.

  2. anntzer commented on Mar 24, 2018

    @anntzer
    Contributor

    bisects to #9452 (so I guess my fault, although what happened is unclear to me :/)

  3. jklymak commented on Mar 25, 2018

    @jklymak
    Member

    I’m always confused about these fcns but I thought they all required a renderer.

  4. WeatherGod commented on Mar 25, 2018

    @WeatherGod
    Member
  5. jklymak commented on Mar 26, 2018

    @jklymak
    Member

    See #10881 and the description of the issue....

  6. added this to the milestone on Mar 27, 2018
  7. jklymak commented on Apr 8, 2018

    @jklymak
    Member

    Cross ref #5665

  8. modified the milestones: v3.0, v3.1 on Aug 11, 2018
  9. Abhijit-2592 commented on Sep 3, 2018

    @Abhijit-2592

    Is it solved yet?
    I am getting the same error. issue persists in version 2.2.3 also. Works as intended with version 2.1.2

  10. jklymak commented on Sep 3, 2018

    @jklymak
    Member

    No. See #10881 and #11004... But #11004 isn't merged yet.

    It seems to me that xtick.get_window_extent() should just take a renderer kwarg as well.

  11. modified the milestones: v3.1, v2.2.4 on Sep 4, 2018
  12. jklymak commented on Sep 4, 2018

    @jklymak
    Member

    ... as a work around until #11004 gets through (ping @efiring), or we ressurect #10881, you can explicitly supply the renderer and all works fine.

    The problem here is that the outermost ticks are never drawn, so their renderer is never set, so the fallback for renderer=None in get_window_extent fails to find the correct renderer.

    for xtick in ax.get_xticklabels():
        bb = xtick.get_window_extent(renderer=fig.canvas.get_renderer())
    for ytick in ax.get_yticklabels():
        ytick.get_window_extent(renderer=fig.canvas.get_renderer())
  13. DocBO commented on Jan 6, 2019

    @DocBO

    Sorry for reopening but in my case in offsetbox.py get_window_extend(self, renderer=None) the line
    renderer = self.figure._cachedRenderer was not the correct solution, therefore I run into the exact same issue.

    Instead, as a workaround I tried
    renderer = self.figure.canvas.get_renderer()
    with success.

    I have at the moment no time to go into deeper details or to create a new case. Sorry for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions