Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ac93ecf

Browse files
committed
Tell IPython the correct GUI event loop to use for all backends.
IPython currently uses a hard-coded table (IPython.core.pylabtools.backend2gui) to know which event loop to use for which backend. This approach fails for both the new builtin cairo-based backends (which do not appear in the table), and for third-party backends (e.g. mplcairo). mplcairo has used some custom code to patch that table for a while; reuse it to more generally use the new "required_interactive_framework" attribute. Note that this PR suggests that there should be a better way to go back from the canvas class to the backend module (rather than looking for `sys.modules[cls.__module__].required_interactive_framework`, which is a bit hacky and could in theory fail if the canvas class is actually defined in another submodule).
1 parent 921d4f4 commit ac93ecf

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"""
3434

3535
from contextlib import contextmanager
36+
import functools
3637
import importlib
3738
import io
3839
import os
@@ -43,6 +44,7 @@
4344

4445
import numpy as np
4546

47+
import matplotlib as mpl
4648
from matplotlib import (
4749
backend_tools as tools, cbook, colors, textpath, tight_bbox, transforms,
4850
widgets, get_backend, is_interactive, rcParams)
@@ -1613,6 +1615,7 @@ class FigureCanvasBase(object):
16131615
'Tagged Image File Format')
16141616

16151617
def __init__(self, figure):
1618+
self._fix_ipython_backend2gui()
16161619
self._is_idle_drawing = True
16171620
self._is_saving = False
16181621
figure.set_canvas(self)
@@ -1629,6 +1632,35 @@ def __init__(self, figure):
16291632
self.toolbar = None # NavigationToolbar2 will set me
16301633
self._is_idle_drawing = False
16311634

1635+
@classmethod
1636+
@functools.lru_cache()
1637+
def _fix_ipython_backend2gui(cls):
1638+
# Fix hard-coded module -> toolkit mapping in IPython (used for
1639+
# `ipython --auto`). This cannot be done at import time due to
1640+
# ordering issues, so we do it when creating a canvas, and should only
1641+
# be done once per class (hence the `lru_cache(1)`).
1642+
if "IPython" not in sys.modules:
1643+
return
1644+
import IPython
1645+
ip = IPython.get_ipython()
1646+
if not ip:
1647+
return
1648+
from IPython.core import pylabtools as pt
1649+
backend_mod = sys.modules[cls.__module__]
1650+
rif = getattr(backend_mod, "required_interactive_framework", None)
1651+
backend2gui_rif = {"qt5": "qt", "qt4": "qt", "gtk3": "gtk3",
1652+
"wx": "wx", "macosx": "osx"}.get(rif)
1653+
if backend2gui_rif:
1654+
pt.backend2gui[get_backend()] = backend2gui_rif
1655+
# Work around pylabtools.find_gui_and_backend always reading from
1656+
# rcParamsOrig.
1657+
orig_origbackend = mpl.rcParamsOrig["backend"]
1658+
try:
1659+
mpl.rcParamsOrig["backend"] = mpl.rcParams["backend"]
1660+
ip.enable_matplotlib()
1661+
finally:
1662+
mpl.rcParamsOrig["backend"] = orig_origbackend
1663+
16321664
@contextmanager
16331665
def _idle_draw_cntx(self):
16341666
self._is_idle_drawing = True

0 commit comments

Comments
 (0)