Skip to content

Commit d677a6a

Browse files
jklymakMeeseeksDev[bot]
authored and
MeeseeksDev[bot]
committed
Backport PR #12637: Tell IPython the correct GUI event loop to use for all backends.
1 parent 8672bfb commit d677a6a

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 37 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,40 @@ 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+
if (not hasattr(pt, "backend2gui")
1601+
or not hasattr(ip, "enable_matplotlib")):
1602+
# In case we ever move the patch to IPython and remove these APIs,
1603+
# don't break on our side.
1604+
return
1605+
backend_mod = sys.modules[cls.__module__]
1606+
rif = getattr(backend_mod, "required_interactive_framework", None)
1607+
backend2gui_rif = {"qt5": "qt", "qt4": "qt", "gtk3": "gtk3",
1608+
"wx": "wx", "macosx": "osx"}.get(rif)
1609+
if backend2gui_rif:
1610+
pt.backend2gui[get_backend()] = backend2gui_rif
1611+
# Work around pylabtools.find_gui_and_backend always reading from
1612+
# rcParamsOrig.
1613+
orig_origbackend = mpl.rcParamsOrig["backend"]
1614+
try:
1615+
mpl.rcParamsOrig["backend"] = mpl.rcParams["backend"]
1616+
ip.enable_matplotlib()
1617+
finally:
1618+
mpl.rcParamsOrig["backend"] = orig_origbackend
1619+
15831620
@contextmanager
15841621
def _idle_draw_cntx(self):
15851622
self._is_idle_drawing = True

0 commit comments

Comments
 (0)