Skip to content

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

@desowin

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

desowin

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.

anntzer

anntzer commented on Mar 24, 2018

@anntzer
Contributor

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

jklymak

jklymak commented on Mar 25, 2018

@jklymak
Member

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

WeatherGod

WeatherGod commented on Mar 25, 2018

@WeatherGod
Member
jklymak

jklymak commented on Mar 26, 2018

@jklymak
Member

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

added this to the v3.0 milestone on Mar 27, 2018
jklymak

jklymak commented on Apr 8, 2018

@jklymak
Member

Cross ref #5665

modified the milestones: v3.0, v3.1 on Aug 11, 2018
Abhijit-2592

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

jklymak

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.

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

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())
DocBO

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

    Relationships

    None yet

      Participants

      @tacaswell@WeatherGod@desowin@anntzer@jklymak

      Issue actions

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