3434
3535from contextlib import contextmanager
3636from enum import IntEnum
37+ import functools
3738import importlib
3839import io
3940import logging
4445
4546import numpy as np
4647
48+ import matplotlib as mpl
4749from matplotlib import (
4850 backend_tools as tools , cbook , colors , textpath , tight_bbox , transforms ,
4951 widgets , get_backend , is_interactive , rcParams )
@@ -1563,6 +1565,7 @@ class FigureCanvasBase(object):
15631565 'Tagged Image File Format' )
15641566
15651567 def __init__ (self , figure ):
1568+ self ._fix_ipython_backend2gui ()
15661569 self ._is_idle_drawing = True
15671570 self ._is_saving = False
15681571 figure .set_canvas (self )
@@ -1579,6 +1582,40 @@ def __init__(self, figure):
15791582 self .toolbar = None # NavigationToolbar2 will set me
15801583 self ._is_idle_drawing = False
15811584
1585+ @classmethod
1586+ @functools .lru_cache ()
1587+ def _fix_ipython_backend2gui (cls ):
1588+ # Fix hard-coded module -> toolkit mapping in IPython (used for
1589+ # `ipython --auto`). This cannot be done at import time due to
1590+ # ordering issues, so we do it when creating a canvas, and should only
1591+ # be done once per class (hence the `lru_cache(1)`).
1592+ if "IPython" not in sys .modules :
1593+ return
1594+ import IPython
1595+ ip = IPython .get_ipython ()
1596+ if not ip :
1597+ return
1598+ from IPython .core import pylabtools as pt
1599+ if (not hasattr (pt , "backend2gui" )
1600+ or not hasattr (ip , "enable_matplotlib" )):
1601+ # In case we ever move the patch to IPython and remove these APIs,
1602+ # don't break on our side.
1603+ return
1604+ backend_mod = sys .modules [cls .__module__ ]
1605+ rif = getattr (backend_mod , "required_interactive_framework" , None )
1606+ backend2gui_rif = {"qt5" : "qt" , "qt4" : "qt" , "gtk3" : "gtk3" ,
1607+ "wx" : "wx" , "macosx" : "osx" }.get (rif )
1608+ if backend2gui_rif :
1609+ pt .backend2gui [get_backend ()] = backend2gui_rif
1610+ # Work around pylabtools.find_gui_and_backend always reading from
1611+ # rcParamsOrig.
1612+ orig_origbackend = mpl .rcParamsOrig ["backend" ]
1613+ try :
1614+ mpl .rcParamsOrig ["backend" ] = mpl .rcParams ["backend" ]
1615+ ip .enable_matplotlib ()
1616+ finally :
1617+ mpl .rcParamsOrig ["backend" ] = orig_origbackend
1618+
15821619 @contextmanager
15831620 def _idle_draw_cntx (self ):
15841621 self ._is_idle_drawing = True
0 commit comments