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

Skip to content

Commit 32ad86f

Browse files
authored
Merge pull request #11896 from anntzer/auto-backend-resolution
ENH: Resolve backend in rcParams.__getitem__("backend").
2 parents 9298960 + ad91933 commit 32ad86f

File tree

6 files changed

+49
-51
lines changed

6 files changed

+49
-51
lines changed

lib/matplotlib/__init__.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137

138138
# cbook must import matplotlib only within function
139139
# definitions, so it is safe to import from it here.
140-
from . import cbook
140+
from . import cbook, rcsetup
141141
from matplotlib.cbook import (
142142
MatplotlibDeprecationWarning, dedent, get_label, sanitize_sequence)
143143
from matplotlib.cbook import mplDeprecation # deprecated
@@ -849,6 +849,10 @@ def __setitem__(self, key, val):
849849
cbook.warn_deprecated(
850850
"3.0", "{} is deprecated; in the future, examples will be "
851851
"found relative to the 'datapath' directory.".format(key))
852+
elif key == 'backend':
853+
if val is rcsetup._auto_backend_sentinel:
854+
if 'backend' in self:
855+
return
852856
try:
853857
cval = self.validate[key](val)
854858
except ValueError as ve:
@@ -877,6 +881,12 @@ def __getitem__(self, key):
877881
"3.0", "{} is deprecated; in the future, examples will be "
878882
"found relative to the 'datapath' directory.".format(key))
879883

884+
elif key == "backend":
885+
val = dict.__getitem__(self, key)
886+
if val is rcsetup._auto_backend_sentinel:
887+
from matplotlib import pyplot as plt
888+
plt.switch_backend(rcsetup._auto_backend_sentinel)
889+
880890
return dict.__getitem__(self, key)
881891

882892
def __repr__(self):
@@ -1091,10 +1101,10 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
10911101
_fullpath = os.path.join(_basedir, rcParams['examples.directory'])
10921102
rcParams['examples.directory'] = _fullpath
10931103

1094-
rcParamsOrig = rcParams.copy()
10951104

10961105
with warnings.catch_warnings():
10971106
warnings.simplefilter("ignore", MatplotlibDeprecationWarning)
1107+
rcParamsOrig = RcParams(rcParams.copy())
10981108
rcParamsDefault = RcParams([(key, default) for key, (default, converter) in
10991109
defaultParams.items()
11001110
if key not in _all_deprecated])
@@ -1218,7 +1228,7 @@ def rc_file_defaults():
12181228
with warnings.catch_warnings():
12191229
warnings.simplefilter("ignore", mplDeprecation)
12201230
from .style.core import STYLE_BLACKLIST
1221-
rcParams.update({k: v for k, v in rcParamsOrig.items()
1231+
rcParams.update({k: rcParamsOrig[k] for k in rcParamsOrig
12221232
if k not in STYLE_BLACKLIST})
12231233

12241234

@@ -1234,7 +1244,8 @@ def rc_file(fname):
12341244
with warnings.catch_warnings():
12351245
warnings.simplefilter("ignore", mplDeprecation)
12361246
from .style.core import STYLE_BLACKLIST
1237-
rcParams.update({k: v for k, v in rc_params_from_file(fname).items()
1247+
rc_from_file = rc_params_from_file(fname)
1248+
rcParams.update({k: rc_from_file[k] for k in rc_from_file
12381249
if k not in STYLE_BLACKLIST})
12391250

12401251

@@ -1285,16 +1296,23 @@ def __init__(self, rc=None, fname=None):
12851296
if rc:
12861297
rcParams.update(rc)
12871298
except Exception:
1288-
# If anything goes wrong, revert to the original rcs.
1289-
dict.update(rcParams, self._orig)
1299+
self.__fallback()
12901300
raise
12911301

1302+
def __fallback(self):
1303+
# If anything goes wrong, revert to the original rcs.
1304+
updated_backend = self._orig['backend']
1305+
dict.update(rcParams, self._orig)
1306+
# except for the backend. If the context block triggered resloving
1307+
# the auto backend resolution keep that value around
1308+
if self._orig['backend'] is rcsetup._auto_backend_sentinel:
1309+
rcParams['backend'] = updated_backend
1310+
12921311
def __enter__(self):
12931312
return self
12941313

12951314
def __exit__(self, exc_type, exc_value, exc_tb):
1296-
# No need to revalidate the original values.
1297-
dict.update(rcParams, self._orig)
1315+
self.__fallback()
12981316

12991317

13001318
def use(arg, warn=True, force=False):
@@ -1320,14 +1338,14 @@ def use(arg, warn=True, force=False):
13201338
13211339
force : bool, optional
13221340
If True, attempt to switch the backend. This defaults to
1323-
false and using `.pyplot.switch_backend` is preferred.
1341+
False.
13241342
13251343
13261344
"""
13271345
name = validate_backend(arg)
13281346

13291347
# if setting back to the same thing, do nothing
1330-
if (rcParams['backend'] == name):
1348+
if (dict.__getitem__(rcParams, 'backend') == name):
13311349
pass
13321350

13331351
# Check if we have already imported pyplot and triggered
@@ -1357,7 +1375,7 @@ def use(arg, warn=True, force=False):
13571375

13581376

13591377
if os.environ.get('MPLBACKEND'):
1360-
use(os.environ['MPLBACKEND'])
1378+
rcParams['backend'] = os.environ.get('MPLBACKEND')
13611379

13621380

13631381
def get_backend():

lib/matplotlib/backends/__init__.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@
1010

1111
_log = logging.getLogger(__name__)
1212

13-
backend = matplotlib.get_backend()
14-
# FIXME: Remove.
15-
_backend_loading_tb = "".join(
16-
line for line in traceback.format_stack()
17-
# Filter out line noise from importlib line.
18-
if not line.startswith(' File "<frozen importlib._bootstrap'))
13+
14+
# NOTE: plt.switch_backend() (called at import time) will add a "backend"
15+
# attribute here for backcompat.
1916

2017

2118
def _get_running_interactive_framework():

lib/matplotlib/pyplot.py

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from matplotlib.backend_bases import FigureCanvasBase
4040
from matplotlib.figure import Figure, figaspect
4141
from matplotlib.gridspec import GridSpec
42-
from matplotlib import rcParams, rcParamsDefault, get_backend
42+
from matplotlib import rcParams, rcParamsDefault, get_backend, rcParamsOrig
4343
from matplotlib import rc_context
4444
from matplotlib.rcsetup import interactive_bk as _interactive_bk
4545
from matplotlib.artist import getp, get, Artist
@@ -67,7 +67,7 @@
6767
Locator, IndexLocator, FixedLocator, NullLocator,\
6868
LinearLocator, LogLocator, AutoLocator, MultipleLocator,\
6969
MaxNLocator
70-
from matplotlib.backends import pylab_setup
70+
from matplotlib.backends import pylab_setup, _get_running_interactive_framework
7171

7272
_log = logging.getLogger(__name__)
7373

@@ -78,35 +78,15 @@
7878
# FIXME: Deprecate.
7979
def _backend_selection():
8080
"""
81-
If rcParams['backend_fallback'] is true, check to see if the
82-
current backend is compatible with the current running event loop,
83-
and if not switches to a compatible one.
84-
"""
85-
backend = rcParams['backend']
86-
if not rcParams['backend_fallback'] or backend not in _interactive_bk:
87-
return
88-
is_agg_backend = rcParams['backend'].endswith('Agg')
89-
if 'wx' in sys.modules and backend not in ('WX', 'WXAgg'):
90-
import wx
91-
if wx.App.IsMainLoopRunning():
92-
rcParams['backend'] = 'wx' + 'Agg' * is_agg_backend
93-
elif 'PyQt4.QtCore' in sys.modules and not backend == 'Qt4Agg':
94-
import PyQt4.QtGui
95-
if not PyQt4.QtGui.qApp.startingUp():
96-
# The mainloop is running.
97-
rcParams['backend'] = 'qt4Agg'
98-
elif 'PyQt5.QtCore' in sys.modules and not backend == 'Qt5Agg':
99-
import PyQt5.QtWidgets
100-
if not PyQt5.QtWidgets.qApp.startingUp():
101-
# The mainloop is running.
102-
rcParams['backend'] = 'qt5Agg'
103-
elif 'gtk' in sys.modules and 'gi' in sys.modules:
104-
from gi.repository import GLib
105-
if GLib.MainLoop().is_running():
106-
rcParams['backend'] = 'GTK3Agg'
107-
elif 'Tkinter' in sys.modules and not backend == 'TkAgg':
108-
# import Tkinter
109-
pass # what if anything do we need to do for tkinter?
81+
If rcParams['backend_fallback'] is true, we will check (at backend
82+
load-time) to see if the current backend is compatible with the current
83+
running event loop, and if not switches to a compatible one.
84+
"""
85+
if rcParams["backend_fallback"]:
86+
if (dict.__getitem__(rcParams, "backend") in _interactive_bk
87+
and _get_running_interactive_framework()):
88+
dict.__setitem__(
89+
rcParams, "backend", rcsetup._auto_backend_sentinel)
11090

11191

11292
_backend_selection()
@@ -237,6 +217,7 @@ def switch_backend(newbackend):
237217
except ImportError:
238218
continue
239219
else:
220+
rcParamsOrig['backend'] = candidate
240221
return
241222

242223
backend_name = (

lib/matplotlib/testing/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def setup():
3636
"Could not set locale to English/United States. "
3737
"Some date-related tests may fail.")
3838

39-
mpl.use('Agg', warn=False) # use Agg backend for these tests
39+
mpl.use('Agg', force=True, warn=False) # use Agg backend for these tests
4040

4141
with warnings.catch_warnings():
4242
warnings.simplefilter("ignore", MatplotlibDeprecationWarning)

lib/matplotlib/testing/conftest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
def pytest_configure(config):
11-
matplotlib.use('agg')
11+
matplotlib.use('agg', force=True)
1212
matplotlib._called_from_pytest = True
1313
matplotlib._init_tests()
1414

@@ -53,6 +53,8 @@ def mpl_test_settings(request):
5353
if backend is not None:
5454
plt.switch_backend(prev_backend)
5555

56+
assert matplotlib.get_backend() == 'agg'
57+
5658

5759
@pytest.fixture
5860
def mpl_image_comparison_parameters(request, extension):

lib/matplotlib/tests/test_backend_svg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def test_determinism(filename, usetex):
139139
[sys.executable, '-R', '-c',
140140
'import matplotlib; '
141141
'matplotlib._called_from_pytest = True; '
142-
'matplotlib.use("svg"); '
142+
'matplotlib.use("svg", force=True); '
143143
'from matplotlib.tests.test_backend_svg '
144144
'import _test_determinism_save;'
145145
'_test_determinism_save(%r, %r)' % (filename, usetex)],

0 commit comments

Comments
 (0)