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

Skip to content

Commit 1254075

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 9221a55 commit 1254075

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
@@ -34,6 +34,7 @@
3434

3535
from contextlib import contextmanager
3636
from enum import IntEnum
37+
import functools
3738
import importlib
3839
import io
3940
import logging
@@ -44,6 +45,7 @@
4445

4546
import numpy as np
4647

48+
import matplotlib as mpl
4749
from matplotlib import (
4850
backend_tools as tools, cbook, colors, textpath, tight_bbox, transforms,
4951
widgets, get_backend, is_interactive, rcParams)
@@ -1564,6 +1566,7 @@ class FigureCanvasBase(object):
15641566
'Tagged Image File Format')
15651567

15661568
def __init__(self, figure):
1569+
self._fix_ipython_backend2gui()
15671570
self._is_idle_drawing = True
15681571
self._is_saving = False
15691572
figure.set_canvas(self)
@@ -1580,6 +1583,35 @@ def __init__(self, figure):
15801583
self.toolbar = None # NavigationToolbar2 will set me
15811584
self._is_idle_drawing = False
15821585

1586+
@classmethod
1587+
@functools.lru_cache()
1588+
def _fix_ipython_backend2gui(cls):
1589+
# Fix hard-coded module -> toolkit mapping in IPython (used for
1590+
# `ipython --auto`). This cannot be done at import time due to
1591+
# ordering issues, so we do it when creating a canvas, and should only
1592+
# be done once per class (hence the `lru_cache(1)`).
1593+
if "IPython" not in sys.modules:
1594+
return
1595+
import IPython
1596+
ip = IPython.get_ipython()
1597+
if not ip:
1598+
return
1599+
from IPython.core import pylabtools as pt
1600+
backend_mod = sys.modules[cls.__module__]
1601+
rif = getattr(backend_mod, "required_interactive_framework", None)
1602+
backend2gui_rif = {"qt5": "qt", "qt4": "qt", "gtk3": "gtk3",
1603+
"wx": "wx", "macosx": "osx"}.get(rif)
1604+
if backend2gui_rif:
1605+
pt.backend2gui[get_backend()] = backend2gui_rif
1606+
# Work around pylabtools.find_gui_and_backend always reading from
1607+
# rcParamsOrig.
1608+
orig_origbackend = mpl.rcParamsOrig["backend"]
1609+
try:
1610+
mpl.rcParamsOrig["backend"] = mpl.rcParams["backend"]
1611+
ip.enable_matplotlib()
1612+
finally:
1613+
mpl.rcParamsOrig["backend"] = orig_origbackend
1614+
15831615
@contextmanager
15841616
def _idle_draw_cntx(self):
15851617
self._is_idle_drawing = True

0 commit comments

Comments
 (0)