|
18 | 18 | The object-oriented API is recommended for more complex plots. |
19 | 19 | """ |
20 | 20 |
|
| 21 | +import importlib |
21 | 22 | import inspect |
| 23 | +import logging |
22 | 24 | from numbers import Number |
23 | 25 | import re |
24 | 26 | import sys |
|
29 | 31 | import matplotlib |
30 | 32 | import matplotlib.colorbar |
31 | 33 | import matplotlib.image |
32 | | -from matplotlib import style |
| 34 | +from matplotlib import rcsetup, style |
33 | 35 | from matplotlib import _pylab_helpers, interactive |
34 | 36 | from matplotlib.cbook import ( |
35 | 37 | dedent, deprecated, silent_list, warn_deprecated, _string_to_bool) |
|
67 | 69 | MaxNLocator |
68 | 70 | from matplotlib.backends import pylab_setup |
69 | 71 |
|
| 72 | +_log = logging.getLogger(__name__) |
| 73 | + |
70 | 74 |
|
71 | 75 | ## Backend detection ## |
72 | 76 |
|
73 | 77 |
|
| 78 | +# FIXME: Deprecate. |
74 | 79 | def _backend_selection(): |
75 | 80 | """ |
76 | 81 | If rcParams['backend_fallback'] is true, check to see if the |
@@ -110,8 +115,6 @@ def _backend_selection(): |
110 | 115 | ## Global ## |
111 | 116 |
|
112 | 117 |
|
113 | | -_backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup() |
114 | | - |
115 | 118 | _IP_REGISTERED = None |
116 | 119 | _INSTALL_FIG_OBSERVER = False |
117 | 120 |
|
@@ -213,21 +216,60 @@ def findobj(o=None, match=None, include_self=True): |
213 | 216 |
|
214 | 217 | def switch_backend(newbackend): |
215 | 218 | """ |
216 | | - Switch the default backend. This feature is **experimental**, and |
217 | | - is only expected to work switching to an image backend. e.g., if |
218 | | - you have a bunch of PostScript scripts that you want to run from |
219 | | - an interactive ipython session, you may want to switch to the PS |
220 | | - backend before running them to avoid having a bunch of GUI windows |
221 | | - popup. If you try to interactively switch from one GUI backend to |
222 | | - another, you will explode. |
| 219 | + Close all open figures and set the Matplotlib backend. |
223 | 220 |
|
224 | | - Calling this command will close all open windows. |
| 221 | + The argument is case-insensitive. Switching to an interactive backend is |
| 222 | + possible only if no event loop for another interactive backend has started. |
| 223 | + Switching to and from non-interactive backends is always possible. |
| 224 | +
|
| 225 | + Parameters |
| 226 | + ---------- |
| 227 | + newbackend : str |
| 228 | + The name of the backend to use. |
225 | 229 | """ |
226 | | - close('all') |
| 230 | + close("all") |
| 231 | + |
| 232 | + if newbackend is rcsetup._auto_backend_sentinel: |
| 233 | + for candidate in ["macosx", "qt5agg", "qt4agg", "gtk3agg", "gtk3cairo", |
| 234 | + "tkagg", "wxagg", "agg", "cairo"]: |
| 235 | + try: |
| 236 | + switch_backend(candidate) |
| 237 | + except ImportError: |
| 238 | + continue |
| 239 | + else: |
| 240 | + return |
| 241 | + |
| 242 | + backend_name = ( |
| 243 | + newbackend[9:] if newbackend.startswith("module://") |
| 244 | + else "matplotlib.backends.backend_{}".format(newbackend.lower())) |
| 245 | + |
| 246 | + backend_mod = importlib.import_module(backend_name) |
| 247 | + Backend = type( |
| 248 | + "Backend", (matplotlib.backends._Backend,), vars(backend_mod)) |
| 249 | + _log.info("Loaded backend %s version %s.", |
| 250 | + newbackend, Backend.backend_version) |
| 251 | + |
| 252 | + required_framework = Backend.required_interactive_framework |
| 253 | + current_framework = \ |
| 254 | + matplotlib.backends._get_running_interactive_framework() |
| 255 | + if (current_framework and required_framework |
| 256 | + and current_framework != required_framework): |
| 257 | + raise ImportError( |
| 258 | + "Cannot load backend {!r} which requires the {!r} interactive " |
| 259 | + "framework, as {!r} is currently running".format( |
| 260 | + newbackend, required_framework, current_framework)) |
| 261 | + |
| 262 | + dict.__setitem__(rcParams, "backend", newbackend) # Don't recurse. |
| 263 | + |
227 | 264 | global _backend_mod, new_figure_manager, draw_if_interactive, _show |
228 | | - matplotlib.use(newbackend, warn=False, force=True) |
229 | | - from matplotlib.backends import pylab_setup |
230 | | - _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup() |
| 265 | + _backend_mod = backend_mod |
| 266 | + new_figure_manager = Backend.new_figure_manager |
| 267 | + draw_if_interactive = Backend.draw_if_interactive |
| 268 | + _show = Backend.show |
| 269 | + |
| 270 | + # Need to keep a global reference to the backend for compatibility reasons. |
| 271 | + # See https://github.com/matplotlib/matplotlib/issues/6092 |
| 272 | + matplotlib.backends.backend = newbackend |
231 | 273 |
|
232 | 274 |
|
233 | 275 | def show(*args, **kw): |
@@ -2358,6 +2400,9 @@ def _autogen_docstring(base): |
2358 | 2400 | # to determine if they should trigger a draw. |
2359 | 2401 | install_repl_displayhook() |
2360 | 2402 |
|
| 2403 | +# Set up the backend. |
| 2404 | +switch_backend(rcParams["backend"]) |
| 2405 | + |
2361 | 2406 |
|
2362 | 2407 | ################# REMAINING CONTENT GENERATED BY boilerplate.py ############## |
2363 | 2408 |
|
|
0 commit comments