Coverage for /usr/lib/python3/dist-packages/matplotlib/__init__.py: 45%
554 statements
« prev ^ index » next coverage.py v7.4.4, created at 2025-06-14 15:25 +0200
« prev ^ index » next coverage.py v7.4.4, created at 2025-06-14 15:25 +0200
1"""
2An object-oriented plotting library.
4A procedural interface is provided by the companion pyplot module,
5which may be imported directly, e.g.::
7 import matplotlib.pyplot as plt
9or using ipython::
11 ipython
13at your terminal, followed by::
15 In [1]: %matplotlib
16 In [2]: import matplotlib.pyplot as plt
18at the ipython shell prompt.
20For the most part, direct use of the explicit object-oriented library is
21encouraged when programming; the implicit pyplot interface is primarily for
22working interactively. The exceptions to this suggestion are the pyplot
23functions `.pyplot.figure`, `.pyplot.subplot`, `.pyplot.subplots`, and
24`.pyplot.savefig`, which can greatly simplify scripting. See
25:ref:`api_interfaces` for an explanation of the tradeoffs between the implicit
26and explicit interfaces.
28Modules include:
30 :mod:`matplotlib.axes`
31 The `~.axes.Axes` class. Most pyplot functions are wrappers for
32 `~.axes.Axes` methods. The axes module is the highest level of OO
33 access to the library.
35 :mod:`matplotlib.figure`
36 The `.Figure` class.
38 :mod:`matplotlib.artist`
39 The `.Artist` base class for all classes that draw things.
41 :mod:`matplotlib.lines`
42 The `.Line2D` class for drawing lines and markers.
44 :mod:`matplotlib.patches`
45 Classes for drawing polygons.
47 :mod:`matplotlib.text`
48 The `.Text` and `.Annotation` classes.
50 :mod:`matplotlib.image`
51 The `.AxesImage` and `.FigureImage` classes.
53 :mod:`matplotlib.collections`
54 Classes for efficient drawing of groups of lines or polygons.
56 :mod:`matplotlib.colors`
57 Color specifications and making colormaps.
59 :mod:`matplotlib.cm`
60 Colormaps, and the `.ScalarMappable` mixin class for providing color
61 mapping functionality to other classes.
63 :mod:`matplotlib.ticker`
64 Calculation of tick mark locations and formatting of tick labels.
66 :mod:`matplotlib.backends`
67 A subpackage with modules for various GUI libraries and output formats.
69The base matplotlib namespace includes:
71 `~matplotlib.rcParams`
72 Default configuration settings; their defaults may be overridden using
73 a :file:`matplotlibrc` file.
75 `~matplotlib.use`
76 Setting the Matplotlib backend. This should be called before any
77 figure is created, because it is not possible to switch between
78 different GUI backends after that.
80Matplotlib was initially written by John D. Hunter (1968-2012) and is now
81developed and maintained by a host of others.
83Occasionally the internal documentation (python docstrings) will refer
84to MATLAB®, a registered trademark of The MathWorks, Inc.
86"""
88import atexit
89from collections import namedtuple
90from collections.abc import MutableMapping
91import contextlib
92import functools
93import importlib
94import inspect
95from inspect import Parameter
96import locale
97import logging
98import os
99from pathlib import Path
100import pprint
101import re
102import shutil
103import subprocess
104import sys
105import tempfile
106import warnings
108import numpy
109from packaging.version import parse as parse_version
111# cbook must import matplotlib only within function
112# definitions, so it is safe to import from it here.
113from . import _api, _version, cbook, _docstring, rcsetup
114from matplotlib.cbook import sanitize_sequence
115from matplotlib._api import MatplotlibDeprecationWarning
116from matplotlib.rcsetup import validate_backend, cycler
119_log = logging.getLogger(__name__)
121__bibtex__ = r"""@Article{Hunter:2007,
122 Author = {Hunter, J. D.},
123 Title = {Matplotlib: A 2D graphics environment},
124 Journal = {Computing in Science \& Engineering},
125 Volume = {9},
126 Number = {3},
127 Pages = {90--95},
128 abstract = {Matplotlib is a 2D graphics package used for Python
129 for application development, interactive scripting, and
130 publication-quality image generation across user
131 interfaces and operating systems.},
132 publisher = {IEEE COMPUTER SOC},
133 year = 2007
134}"""
136# modelled after sys.version_info
137_VersionInfo = namedtuple('_VersionInfo',
138 'major, minor, micro, releaselevel, serial')
141def _parse_to_version_info(version_str):
142 """
143 Parse a version string to a namedtuple analogous to sys.version_info.
145 See:
146 https://packaging.pypa.io/en/latest/version.html#packaging.version.parse
147 https://docs.python.org/3/library/sys.html#sys.version_info
148 """
149 v = parse_version(version_str)
150 if v.pre is None and v.post is None and v.dev is None:
151 return _VersionInfo(v.major, v.minor, v.micro, 'final', 0)
152 elif v.dev is not None:
153 return _VersionInfo(v.major, v.minor, v.micro, 'alpha', v.dev)
154 elif v.pre is not None:
155 releaselevel = {
156 'a': 'alpha',
157 'b': 'beta',
158 'rc': 'candidate'}.get(v.pre[0], 'alpha')
159 return _VersionInfo(v.major, v.minor, v.micro, releaselevel, v.pre[1])
160 else:
161 # fallback for v.post: guess-next-dev scheme from setuptools_scm
162 return _VersionInfo(v.major, v.minor, v.micro + 1, 'alpha', v.post)
165def _get_version():
166 """Return the version string used for __version__."""
167 # Only shell out to a git subprocess if really needed, i.e. when we are in
168 # a matplotlib git repo but not in a shallow clone, such as those used by
169 # CI, as the latter would trigger a warning from setuptools_scm.
170 root = Path(__file__).resolve().parents[2]
171 if ((root / ".matplotlib-repo").exists()
172 and (root / ".git").exists()
173 and not (root / ".git/shallow").exists()):
174 import setuptools_scm
175 return setuptools_scm.get_version(
176 root=root,
177 version_scheme="release-branch-semver",
178 local_scheme="node-and-date",
179 fallback_version=_version.version,
180 )
181 else: # Get the version from the _version.py setuptools_scm file.
182 return _version.version
185@_api.caching_module_getattr
186class __getattr__:
187 __version__ = property(lambda self: _get_version())
188 __version_info__ = property(
189 lambda self: _parse_to_version_info(self.__version__))
190 # module-level deprecations
191 URL_REGEX = _api.deprecated("3.5", obj_type="")(property(
192 lambda self: re.compile(r'^http://|^https://|^ftp://|^file:')))
195def _check_versions():
197 # Quickfix to ensure Microsoft Visual C++ redistributable
198 # DLLs are loaded before importing kiwisolver
199 from . import ft2font
201 for modname, minver in [
202 ("cycler", "0.10"),
203 ("dateutil", "2.7"),
204 ("kiwisolver", "1.0.1"),
205 ("numpy", "1.19"),
206 ("pyparsing", "2.2.1"),
207 ]:
208 module = importlib.import_module(modname)
209 if parse_version(module.__version__) < parse_version(minver):
210 raise ImportError(f"Matplotlib requires {modname}>={minver}; "
211 f"you have {module.__version__}")
214_check_versions()
217# The decorator ensures this always returns the same handler (and it is only
218# attached once).
219@functools.lru_cache()
220def _ensure_handler():
221 """
222 The first time this function is called, attach a `StreamHandler` using the
223 same format as `logging.basicConfig` to the Matplotlib root logger.
225 Return this handler every time this function is called.
226 """
227 handler = logging.StreamHandler()
228 handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
229 _log.addHandler(handler)
230 return handler
233def set_loglevel(level):
234 """
235 Set Matplotlib's root logger and root logger handler level, creating
236 the handler if it does not exist yet.
238 Typically, one should call ``set_loglevel("info")`` or
239 ``set_loglevel("debug")`` to get additional debugging information.
241 Parameters
242 ----------
243 level : {"notset", "debug", "info", "warning", "error", "critical"}
244 The log level of the handler.
246 Notes
247 -----
248 The first time this function is called, an additional handler is attached
249 to Matplotlib's root handler; this handler is reused every time and this
250 function simply manipulates the logger and handler's level.
251 """
252 _log.setLevel(level.upper())
253 _ensure_handler().setLevel(level.upper())
256def _logged_cached(fmt, func=None):
257 """
258 Decorator that logs a function's return value, and memoizes that value.
260 After ::
262 @_logged_cached(fmt)
263 def func(): ...
265 the first call to *func* will log its return value at the DEBUG level using
266 %-format string *fmt*, and memoize it; later calls to *func* will directly
267 return that value.
268 """
269 if func is None: # Return the actual decorator.
270 return functools.partial(_logged_cached, fmt)
272 called = False
273 ret = None
275 @functools.wraps(func)
276 def wrapper(**kwargs):
277 nonlocal called, ret
278 if not called:
279 ret = func(**kwargs)
280 called = True
281 _log.debug(fmt, ret)
282 return ret
284 return wrapper
287_ExecInfo = namedtuple("_ExecInfo", "executable raw_version version")
290class ExecutableNotFoundError(FileNotFoundError):
291 """
292 Error raised when an executable that Matplotlib optionally
293 depends on can't be found.
294 """
295 pass
298@functools.lru_cache()
299def _get_executable_info(name):
300 """
301 Get the version of some executable that Matplotlib optionally depends on.
303 .. warning::
304 The list of executables that this function supports is set according to
305 Matplotlib's internal needs, and may change without notice.
307 Parameters
308 ----------
309 name : str
310 The executable to query. The following values are currently supported:
311 "dvipng", "gs", "inkscape", "magick", "pdftocairo", "pdftops". This
312 list is subject to change without notice.
314 Returns
315 -------
316 tuple
317 A namedtuple with fields ``executable`` (`str`) and ``version``
318 (`packaging.Version`, or ``None`` if the version cannot be determined).
320 Raises
321 ------
322 ExecutableNotFoundError
323 If the executable is not found or older than the oldest version
324 supported by Matplotlib. For debugging purposes, it is also
325 possible to "hide" an executable from Matplotlib by adding it to the
326 :envvar:`_MPLHIDEEXECUTABLES` environment variable (a comma-separated
327 list), which must be set prior to any calls to this function.
328 ValueError
329 If the executable is not one that we know how to query.
330 """
332 def impl(args, regex, min_ver=None, ignore_exit_code=False):
333 # Execute the subprocess specified by args; capture stdout and stderr.
334 # Search for a regex match in the output; if the match succeeds, the
335 # first group of the match is the version.
336 # Return an _ExecInfo if the executable exists, and has a version of
337 # at least min_ver (if set); else, raise ExecutableNotFoundError.
338 try:
339 output = subprocess.check_output(
340 args, stderr=subprocess.STDOUT,
341 universal_newlines=True, errors="replace")
342 except subprocess.CalledProcessError as _cpe:
343 if ignore_exit_code:
344 output = _cpe.output
345 else:
346 raise ExecutableNotFoundError(str(_cpe)) from _cpe
347 except OSError as _ose:
348 raise ExecutableNotFoundError(str(_ose)) from _ose
349 match = re.search(regex, output)
350 if match:
351 raw_version = match.group(1)
352 version = parse_version(raw_version)
353 if min_ver is not None and version < parse_version(min_ver):
354 raise ExecutableNotFoundError(
355 f"You have {args[0]} version {version} but the minimum "
356 f"version supported by Matplotlib is {min_ver}")
357 return _ExecInfo(args[0], raw_version, version)
358 else:
359 raise ExecutableNotFoundError(
360 f"Failed to determine the version of {args[0]} from "
361 f"{' '.join(args)}, which output {output}")
363 if name in os.environ.get("_MPLHIDEEXECUTABLES", "").split(","):
364 raise ExecutableNotFoundError(f"{name} was hidden")
366 if name == "dvipng":
367 return impl(["dvipng", "-version"], "(?m)^dvipng(?: .*)? (.+)", "1.6")
368 elif name == "gs":
369 execs = (["gswin32c", "gswin64c", "mgs", "gs"] # "mgs" for miktex.
370 if sys.platform == "win32" else
371 ["gs"])
372 for e in execs:
373 try:
374 return impl([e, "--version"], "(.*)", "9")
375 except ExecutableNotFoundError:
376 pass
377 message = "Failed to find a Ghostscript installation"
378 raise ExecutableNotFoundError(message)
379 elif name == "inkscape":
380 try:
381 # Try headless option first (needed for Inkscape version < 1.0):
382 return impl(["inkscape", "--without-gui", "-V"],
383 "Inkscape ([^ ]*)")
384 except ExecutableNotFoundError:
385 pass # Suppress exception chaining.
386 # If --without-gui is not accepted, we may be using Inkscape >= 1.0 so
387 # try without it:
388 return impl(["inkscape", "-V"], "Inkscape ([^ ]*)")
389 elif name == "magick":
390 if sys.platform == "win32":
391 # Check the registry to avoid confusing ImageMagick's convert with
392 # Windows's builtin convert.exe.
393 import winreg
394 binpath = ""
395 for flag in [0, winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY]:
396 try:
397 with winreg.OpenKeyEx(
398 winreg.HKEY_LOCAL_MACHINE,
399 r"Software\Imagemagick\Current",
400 0, winreg.KEY_QUERY_VALUE | flag) as hkey:
401 binpath = winreg.QueryValueEx(hkey, "BinPath")[0]
402 except OSError:
403 pass
404 path = None
405 if binpath:
406 for name in ["convert.exe", "magick.exe"]:
407 candidate = Path(binpath, name)
408 if candidate.exists():
409 path = str(candidate)
410 break
411 if path is None:
412 raise ExecutableNotFoundError(
413 "Failed to find an ImageMagick installation")
414 else:
415 path = "convert"
416 info = impl([path, "--version"], r"^Version: ImageMagick (\S*)")
417 if info.raw_version == "7.0.10-34":
418 # https://github.com/ImageMagick/ImageMagick/issues/2720
419 raise ExecutableNotFoundError(
420 f"You have ImageMagick {info.version}, which is unsupported")
421 return info
422 elif name == "pdftocairo":
423 return impl(["pdftocairo", "-v"], "pdftocairo version (.*)")
424 elif name == "pdftops":
425 info = impl(["pdftops", "-v"], "^pdftops version (.*)",
426 ignore_exit_code=True)
427 if info and not (
428 3 <= info.version.major or
429 # poppler version numbers.
430 parse_version("0.9") <= info.version < parse_version("1.0")):
431 raise ExecutableNotFoundError(
432 f"You have pdftops version {info.version} but the minimum "
433 f"version supported by Matplotlib is 3.0")
434 return info
435 else:
436 raise ValueError("Unknown executable: {!r}".format(name))
439@_api.deprecated("3.6", alternative="a vendored copy of this function")
440def checkdep_usetex(s):
441 if not s:
442 return False
443 if not shutil.which("tex"):
444 _log.warning("usetex mode requires TeX.")
445 return False
446 try:
447 _get_executable_info("dvipng")
448 except ExecutableNotFoundError:
449 _log.warning("usetex mode requires dvipng.")
450 return False
451 try:
452 _get_executable_info("gs")
453 except ExecutableNotFoundError:
454 _log.warning("usetex mode requires ghostscript.")
455 return False
456 return True
459def _get_xdg_config_dir():
460 """
461 Return the XDG configuration directory, according to the XDG base
462 directory spec:
464 https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
465 """
466 return os.environ.get('XDG_CONFIG_HOME') or str(Path.home() / ".config")
469def _get_xdg_cache_dir():
470 """
471 Return the XDG cache directory, according to the XDG base directory spec:
473 https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
474 """
475 return os.environ.get('XDG_CACHE_HOME') or str(Path.home() / ".cache")
478def _get_config_or_cache_dir(xdg_base_getter):
479 configdir = os.environ.get('MPLCONFIGDIR')
480 if configdir:
481 configdir = Path(configdir).resolve()
482 elif sys.platform.startswith(('linux', 'freebsd')):
483 # Only call _xdg_base_getter here so that MPLCONFIGDIR is tried first,
484 # as _xdg_base_getter can throw.
485 configdir = Path(xdg_base_getter(), "matplotlib")
486 else:
487 configdir = Path.home() / ".matplotlib"
488 try:
489 configdir.mkdir(parents=True, exist_ok=True)
490 except OSError:
491 pass
492 else:
493 if os.access(str(configdir), os.W_OK) and configdir.is_dir():
494 return str(configdir)
495 # If the config or cache directory cannot be created or is not a writable
496 # directory, create a temporary one.
497 tmpdir = os.environ["MPLCONFIGDIR"] = \
498 tempfile.mkdtemp(prefix="matplotlib-")
499 atexit.register(shutil.rmtree, tmpdir)
500 _log.warning(
501 "Matplotlib created a temporary config/cache directory at %s because "
502 "the default path (%s) is not a writable directory; it is highly "
503 "recommended to set the MPLCONFIGDIR environment variable to a "
504 "writable directory, in particular to speed up the import of "
505 "Matplotlib and to better support multiprocessing.",
506 tmpdir, configdir)
507 return tmpdir
510@_logged_cached('CONFIGDIR=%s')
511def get_configdir():
512 """
513 Return the string path of the configuration directory.
515 The directory is chosen as follows:
517 1. If the MPLCONFIGDIR environment variable is supplied, choose that.
518 2. On Linux, follow the XDG specification and look first in
519 ``$XDG_CONFIG_HOME``, if defined, or ``$HOME/.config``. On other
520 platforms, choose ``$HOME/.matplotlib``.
521 3. If the chosen directory exists and is writable, use that as the
522 configuration directory.
523 4. Else, create a temporary directory, and use it as the configuration
524 directory.
525 """
526 return _get_config_or_cache_dir(_get_xdg_config_dir)
529@_logged_cached('CACHEDIR=%s')
530def get_cachedir():
531 """
532 Return the string path of the cache directory.
534 The procedure used to find the directory is the same as for
535 _get_config_dir, except using ``$XDG_CACHE_HOME``/``$HOME/.cache`` instead.
536 """
537 return _get_config_or_cache_dir(_get_xdg_cache_dir)
540@_logged_cached('matplotlib data path: %s')
541def get_data_path():
542 """Return the path to Matplotlib data."""
543 _data_path = Path(__file__).with_name("mpl-data")
544 if _data_path.exists():
545 return str(_data_path)
546 else:
547 return '/usr/share/matplotlib/mpl-data'
550def matplotlib_fname():
551 """
552 Get the location of the config file.
554 The file location is determined in the following order
556 - ``$PWD/matplotlibrc``
557 - ``$MATPLOTLIBRC`` if it is not a directory
558 - ``$MATPLOTLIBRC/matplotlibrc``
559 - ``$MPLCONFIGDIR/matplotlibrc``
560 - On Linux,
561 - ``$XDG_CONFIG_HOME/matplotlib/matplotlibrc`` (if ``$XDG_CONFIG_HOME``
562 is defined)
563 - or ``$HOME/.config/matplotlib/matplotlibrc`` (if ``$XDG_CONFIG_HOME``
564 is not defined)
565 - On other platforms,
566 - ``$HOME/.matplotlib/matplotlibrc`` if ``$HOME`` is defined
567 - Lastly, it looks in ``$MATPLOTLIBDATA/matplotlibrc``, which should always
568 exist.
569 """
571 def gen_candidates():
572 # rely on down-stream code to make absolute. This protects us
573 # from having to directly get the current working directory
574 # which can fail if the user has ended up with a cwd that is
575 # non-existent.
576 yield 'matplotlibrc'
577 try:
578 matplotlibrc = os.environ['MATPLOTLIBRC']
579 except KeyError:
580 pass
581 else:
582 yield matplotlibrc
583 yield os.path.join(matplotlibrc, 'matplotlibrc')
584 yield os.path.join(get_configdir(), 'matplotlibrc')
585 yield '/etc/matplotlibrc'
587 for fname in gen_candidates():
588 if os.path.exists(fname) and not os.path.isdir(fname):
589 return fname
591 raise RuntimeError("Could not find matplotlibrc file; your Matplotlib "
592 "install is broken")
595# rcParams deprecated and automatically mapped to another key.
596# Values are tuples of (version, new_name, f_old2new, f_new2old).
597_deprecated_map = {}
598# rcParams deprecated; some can manually be mapped to another key.
599# Values are tuples of (version, new_name_or_None).
600_deprecated_ignore_map = {}
601# rcParams deprecated; can use None to suppress warnings; remain actually
602# listed in the rcParams.
603# Values are tuples of (version,)
604_deprecated_remain_as_none = {}
607@_docstring.Substitution(
608 "\n".join(map("- {}".format, sorted(rcsetup._validators, key=str.lower)))
609)
610class RcParams(MutableMapping, dict):
611 """
612 A dictionary object including validation.
614 Validating functions are defined and associated with rc parameters in
615 :mod:`matplotlib.rcsetup`.
617 The list of rcParams is:
619 %s
621 See Also
622 --------
623 :ref:`customizing-with-matplotlibrc-files`
624 """
626 validate = rcsetup._validators
628 # validate values on the way in
629 def __init__(self, *args, **kwargs):
630 self.update(*args, **kwargs)
632 def __setitem__(self, key, val):
633 try:
634 if key in _deprecated_map:
635 version, alt_key, alt_val, inverse_alt = _deprecated_map[key]
636 _api.warn_deprecated(
637 version, name=key, obj_type="rcparam", alternative=alt_key)
638 key = alt_key
639 val = alt_val(val)
640 elif key in _deprecated_remain_as_none and val is not None:
641 version, = _deprecated_remain_as_none[key]
642 _api.warn_deprecated(version, name=key, obj_type="rcparam")
643 elif key in _deprecated_ignore_map:
644 version, alt_key = _deprecated_ignore_map[key]
645 _api.warn_deprecated(
646 version, name=key, obj_type="rcparam", alternative=alt_key)
647 return
648 elif key == 'backend':
649 if val is rcsetup._auto_backend_sentinel:
650 if 'backend' in self:
651 return
652 try:
653 cval = self.validate[key](val)
654 except ValueError as ve:
655 raise ValueError(f"Key {key}: {ve}") from None
656 dict.__setitem__(self, key, cval)
657 except KeyError as err:
658 raise KeyError(
659 f"{key} is not a valid rc parameter (see rcParams.keys() for "
660 f"a list of valid parameters)") from err
662 def __getitem__(self, key):
663 if key in _deprecated_map:
664 version, alt_key, alt_val, inverse_alt = _deprecated_map[key]
665 _api.warn_deprecated(
666 version, name=key, obj_type="rcparam", alternative=alt_key)
667 return inverse_alt(dict.__getitem__(self, alt_key))
669 elif key in _deprecated_ignore_map:
670 version, alt_key = _deprecated_ignore_map[key]
671 _api.warn_deprecated(
672 version, name=key, obj_type="rcparam", alternative=alt_key)
673 return dict.__getitem__(self, alt_key) if alt_key else None
675 # In theory, this should only ever be used after the global rcParams
676 # has been set up, but better be safe e.g. in presence of breakpoints.
677 elif key == "backend" and self is globals().get("rcParams"):
678 val = dict.__getitem__(self, key)
679 if val is rcsetup._auto_backend_sentinel:
680 from matplotlib import pyplot as plt
681 plt.switch_backend(rcsetup._auto_backend_sentinel)
683 return dict.__getitem__(self, key)
685 def _get_backend_or_none(self):
686 """Get the requested backend, if any, without triggering resolution."""
687 backend = dict.__getitem__(self, "backend")
688 return None if backend is rcsetup._auto_backend_sentinel else backend
690 def __repr__(self):
691 class_name = self.__class__.__name__
692 indent = len(class_name) + 1
693 with _api.suppress_matplotlib_deprecation_warning():
694 repr_split = pprint.pformat(dict(self), indent=1,
695 width=80 - indent).split('\n')
696 repr_indented = ('\n' + ' ' * indent).join(repr_split)
697 return '{}({})'.format(class_name, repr_indented)
699 def __str__(self):
700 return '\n'.join(map('{0[0]}: {0[1]}'.format, sorted(self.items())))
702 def __iter__(self):
703 """Yield sorted list of keys."""
704 with _api.suppress_matplotlib_deprecation_warning():
705 yield from sorted(dict.__iter__(self))
707 def __len__(self):
708 return dict.__len__(self)
710 def find_all(self, pattern):
711 """
712 Return the subset of this RcParams dictionary whose keys match,
713 using :func:`re.search`, the given ``pattern``.
715 .. note::
717 Changes to the returned dictionary are *not* propagated to
718 the parent RcParams dictionary.
720 """
721 pattern_re = re.compile(pattern)
722 return RcParams((key, value)
723 for key, value in self.items()
724 if pattern_re.search(key))
726 def copy(self):
727 """Copy this RcParams instance."""
728 rccopy = RcParams()
729 for k in self: # Skip deprecations and revalidation.
730 dict.__setitem__(rccopy, k, dict.__getitem__(self, k))
731 return rccopy
734def rc_params(fail_on_error=False):
735 """Construct a `RcParams` instance from the default Matplotlib rc file."""
736 return rc_params_from_file(matplotlib_fname(), fail_on_error)
739@_api.deprecated("3.5")
740def is_url(filename):
741 """Return whether *filename* is an http, https, ftp, or file URL path."""
742 return __getattr__("URL_REGEX").match(filename) is not None
745@functools.lru_cache()
746def _get_ssl_context():
747 try:
748 import certifi
749 except ImportError:
750 _log.debug("Could not import certifi.")
751 return None
752 import ssl
753 return ssl.create_default_context(cafile=certifi.where())
756@contextlib.contextmanager
757def _open_file_or_url(fname):
758 if (isinstance(fname, str)
759 and fname.startswith(('http://', 'https://', 'ftp://', 'file:'))):
760 import urllib.request
761 ssl_ctx = _get_ssl_context()
762 if ssl_ctx is None:
763 _log.debug(
764 "Could not get certifi ssl context, https may not work."
765 )
766 with urllib.request.urlopen(fname, context=ssl_ctx) as f:
767 yield (line.decode('utf-8') for line in f)
768 else:
769 fname = os.path.expanduser(fname)
770 with open(fname, encoding='utf-8') as f:
771 yield f
774def _rc_params_in_file(fname, transform=lambda x: x, fail_on_error=False):
775 """
776 Construct a `RcParams` instance from file *fname*.
778 Unlike `rc_params_from_file`, the configuration class only contains the
779 parameters specified in the file (i.e. default values are not filled in).
781 Parameters
782 ----------
783 fname : path-like
784 The loaded file.
785 transform : callable, default: the identity function
786 A function called on each individual line of the file to transform it,
787 before further parsing.
788 fail_on_error : bool, default: False
789 Whether invalid entries should result in an exception or a warning.
790 """
791 import matplotlib as mpl
792 rc_temp = {}
793 with _open_file_or_url(fname) as fd:
794 try:
795 for line_no, line in enumerate(fd, 1):
796 line = transform(line)
797 strippedline = cbook._strip_comment(line)
798 if not strippedline:
799 continue
800 tup = strippedline.split(':', 1)
801 if len(tup) != 2:
802 _log.warning('Missing colon in file %r, line %d (%r)',
803 fname, line_no, line.rstrip('\n'))
804 continue
805 key, val = tup
806 key = key.strip()
807 val = val.strip()
808 if val.startswith('"') and val.endswith('"'):
809 val = val[1:-1] # strip double quotes
810 if key in rc_temp:
811 _log.warning('Duplicate key in file %r, line %d (%r)',
812 fname, line_no, line.rstrip('\n'))
813 rc_temp[key] = (val, line, line_no)
814 except UnicodeDecodeError:
815 _log.warning('Cannot decode configuration file %r as utf-8.',
816 fname)
817 raise
819 config = RcParams()
821 for key, (val, line, line_no) in rc_temp.items():
822 if key in rcsetup._validators:
823 if fail_on_error:
824 config[key] = val # try to convert to proper type or raise
825 else:
826 try:
827 config[key] = val # try to convert to proper type or skip
828 except Exception as msg:
829 _log.warning('Bad value in file %r, line %d (%r): %s',
830 fname, line_no, line.rstrip('\n'), msg)
831 elif key in _deprecated_ignore_map:
832 version, alt_key = _deprecated_ignore_map[key]
833 _api.warn_deprecated(
834 version, name=key, alternative=alt_key, obj_type='rcparam',
835 addendum="Please update your matplotlibrc.")
836 else:
837 # __version__ must be looked up as an attribute to trigger the
838 # module-level __getattr__.
839 version = ('main' if '.post' in mpl.__version__
840 else f'v{mpl.__version__}')
841 _log.warning("""
842Bad key %(key)s in file %(fname)s, line %(line_no)s (%(line)r)
843You probably need to get an updated matplotlibrc file from
844https://github.com/matplotlib/matplotlib/blob/%(version)s/matplotlibrc.template
845or from the matplotlib source distribution""",
846 dict(key=key, fname=fname, line_no=line_no,
847 line=line.rstrip('\n'), version=version))
848 return config
851def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
852 """
853 Construct a `RcParams` from file *fname*.
855 Parameters
856 ----------
857 fname : str or path-like
858 A file with Matplotlib rc settings.
859 fail_on_error : bool
860 If True, raise an error when the parser fails to convert a parameter.
861 use_default_template : bool
862 If True, initialize with default parameters before updating with those
863 in the given file. If False, the configuration class only contains the
864 parameters specified in the file. (Useful for updating dicts.)
865 """
866 config_from_file = _rc_params_in_file(fname, fail_on_error=fail_on_error)
868 if not use_default_template:
869 return config_from_file
871 with _api.suppress_matplotlib_deprecation_warning():
872 config = RcParams({**rcParamsDefault, **config_from_file})
874 if "".join(config['text.latex.preamble']):
875 _log.info("""
876*****************************************************************
877You have the following UNSUPPORTED LaTeX preamble customizations:
878%s
879Please do not ask for support with these customizations active.
880*****************************************************************
881""", '\n'.join(config['text.latex.preamble']))
882 _log.debug('loaded rc file %s', fname)
884 return config
887# When constructing the global instances, we need to perform certain updates
888# by explicitly calling the superclass (dict.update, dict.items) to avoid
889# triggering resolution of _auto_backend_sentinel.
890rcParamsDefault = _rc_params_in_file(
891 cbook._get_data_path("matplotlibrc"),
892 # Strip leading comment.
893 transform=lambda line: line[1:] if line.startswith("#") else line,
894 fail_on_error=True)
895dict.update(rcParamsDefault, rcsetup._hardcoded_defaults)
896# Normally, the default matplotlibrc file contains *no* entry for backend (the
897# corresponding line starts with ##, not #; we fill on _auto_backend_sentinel
898# in that case. However, packagers can set a different default backend
899# (resulting in a normal `#backend: foo` line) in which case we should *not*
900# fill in _auto_backend_sentinel.
901dict.setdefault(rcParamsDefault, "backend", rcsetup._auto_backend_sentinel)
902rcParams = RcParams() # The global instance.
903dict.update(rcParams, dict.items(rcParamsDefault))
904dict.update(rcParams, _rc_params_in_file(matplotlib_fname()))
905rcParamsOrig = rcParams.copy()
906with _api.suppress_matplotlib_deprecation_warning():
907 # This also checks that all rcParams are indeed listed in the template.
908 # Assigning to rcsetup.defaultParams is left only for backcompat.
909 defaultParams = rcsetup.defaultParams = {
910 # We want to resolve deprecated rcParams, but not backend...
911 key: [(rcsetup._auto_backend_sentinel if key == "backend" else
912 rcParamsDefault[key]),
913 validator]
914 for key, validator in rcsetup._validators.items()}
915if rcParams['axes.formatter.use_locale']:
916 locale.setlocale(locale.LC_ALL, '')
919def rc(group, **kwargs):
920 """
921 Set the current `.rcParams`. *group* is the grouping for the rc, e.g.,
922 for ``lines.linewidth`` the group is ``lines``, for
923 ``axes.facecolor``, the group is ``axes``, and so on. Group may
924 also be a list or tuple of group names, e.g., (*xtick*, *ytick*).
925 *kwargs* is a dictionary attribute name/value pairs, e.g.,::
927 rc('lines', linewidth=2, color='r')
929 sets the current `.rcParams` and is equivalent to::
931 rcParams['lines.linewidth'] = 2
932 rcParams['lines.color'] = 'r'
934 The following aliases are available to save typing for interactive users:
936 ===== =================
937 Alias Property
938 ===== =================
939 'lw' 'linewidth'
940 'ls' 'linestyle'
941 'c' 'color'
942 'fc' 'facecolor'
943 'ec' 'edgecolor'
944 'mew' 'markeredgewidth'
945 'aa' 'antialiased'
946 ===== =================
948 Thus you could abbreviate the above call as::
950 rc('lines', lw=2, c='r')
952 Note you can use python's kwargs dictionary facility to store
953 dictionaries of default parameters. e.g., you can customize the
954 font rc as follows::
956 font = {'family' : 'monospace',
957 'weight' : 'bold',
958 'size' : 'larger'}
959 rc('font', **font) # pass in the font dict as kwargs
961 This enables you to easily switch between several configurations. Use
962 ``matplotlib.style.use('default')`` or :func:`~matplotlib.rcdefaults` to
963 restore the default `.rcParams` after changes.
965 Notes
966 -----
967 Similar functionality is available by using the normal dict interface, i.e.
968 ``rcParams.update({"lines.linewidth": 2, ...})`` (but ``rcParams.update``
969 does not support abbreviations or grouping).
970 """
972 aliases = {
973 'lw': 'linewidth',
974 'ls': 'linestyle',
975 'c': 'color',
976 'fc': 'facecolor',
977 'ec': 'edgecolor',
978 'mew': 'markeredgewidth',
979 'aa': 'antialiased',
980 }
982 if isinstance(group, str):
983 group = (group,)
984 for g in group:
985 for k, v in kwargs.items():
986 name = aliases.get(k) or k
987 key = '%s.%s' % (g, name)
988 try:
989 rcParams[key] = v
990 except KeyError as err:
991 raise KeyError(('Unrecognized key "%s" for group "%s" and '
992 'name "%s"') % (key, g, name)) from err
995def rcdefaults():
996 """
997 Restore the `.rcParams` from Matplotlib's internal default style.
999 Style-blacklisted `.rcParams` (defined in
1000 ``matplotlib.style.core.STYLE_BLACKLIST``) are not updated.
1002 See Also
1003 --------
1004 matplotlib.rc_file_defaults
1005 Restore the `.rcParams` from the rc file originally loaded by
1006 Matplotlib.
1007 matplotlib.style.use
1008 Use a specific style file. Call ``style.use('default')`` to restore
1009 the default style.
1010 """
1011 # Deprecation warnings were already handled when creating rcParamsDefault,
1012 # no need to reemit them here.
1013 with _api.suppress_matplotlib_deprecation_warning():
1014 from .style.core import STYLE_BLACKLIST
1015 rcParams.clear()
1016 rcParams.update({k: v for k, v in rcParamsDefault.items()
1017 if k not in STYLE_BLACKLIST})
1020def rc_file_defaults():
1021 """
1022 Restore the `.rcParams` from the original rc file loaded by Matplotlib.
1024 Style-blacklisted `.rcParams` (defined in
1025 ``matplotlib.style.core.STYLE_BLACKLIST``) are not updated.
1026 """
1027 # Deprecation warnings were already handled when creating rcParamsOrig, no
1028 # need to reemit them here.
1029 with _api.suppress_matplotlib_deprecation_warning():
1030 from .style.core import STYLE_BLACKLIST
1031 rcParams.update({k: rcParamsOrig[k] for k in rcParamsOrig
1032 if k not in STYLE_BLACKLIST})
1035def rc_file(fname, *, use_default_template=True):
1036 """
1037 Update `.rcParams` from file.
1039 Style-blacklisted `.rcParams` (defined in
1040 ``matplotlib.style.core.STYLE_BLACKLIST``) are not updated.
1042 Parameters
1043 ----------
1044 fname : str or path-like
1045 A file with Matplotlib rc settings.
1047 use_default_template : bool
1048 If True, initialize with default parameters before updating with those
1049 in the given file. If False, the current configuration persists
1050 and only the parameters specified in the file are updated.
1051 """
1052 # Deprecation warnings were already handled in rc_params_from_file, no need
1053 # to reemit them here.
1054 with _api.suppress_matplotlib_deprecation_warning():
1055 from .style.core import STYLE_BLACKLIST
1056 rc_from_file = rc_params_from_file(
1057 fname, use_default_template=use_default_template)
1058 rcParams.update({k: rc_from_file[k] for k in rc_from_file
1059 if k not in STYLE_BLACKLIST})
1062@contextlib.contextmanager
1063def rc_context(rc=None, fname=None):
1064 """
1065 Return a context manager for temporarily changing rcParams.
1067 The :rc:`backend` will not be reset by the context manager.
1069 rcParams changed both through the context manager invocation and
1070 in the body of the context will be reset on context exit.
1072 Parameters
1073 ----------
1074 rc : dict
1075 The rcParams to temporarily set.
1076 fname : str or path-like
1077 A file with Matplotlib rc settings. If both *fname* and *rc* are given,
1078 settings from *rc* take precedence.
1080 See Also
1081 --------
1082 :ref:`customizing-with-matplotlibrc-files`
1084 Examples
1085 --------
1086 Passing explicit values via a dict::
1088 with mpl.rc_context({'interactive': False}):
1089 fig, ax = plt.subplots()
1090 ax.plot(range(3), range(3))
1091 fig.savefig('example.png')
1092 plt.close(fig)
1094 Loading settings from a file::
1096 with mpl.rc_context(fname='print.rc'):
1097 plt.plot(x, y) # uses 'print.rc'
1099 Setting in the context body::
1101 with mpl.rc_context():
1102 # will be reset
1103 mpl.rcParams['lines.linewidth'] = 5
1104 plt.plot(x, y)
1106 """
1107 orig = dict(rcParams.copy())
1108 del orig['backend']
1109 try:
1110 if fname:
1111 rc_file(fname)
1112 if rc:
1113 rcParams.update(rc)
1114 yield
1115 finally:
1116 dict.update(rcParams, orig) # Revert to the original rcs.
1119def use(backend, *, force=True):
1120 """
1121 Select the backend used for rendering and GUI integration.
1123 Parameters
1124 ----------
1125 backend : str
1126 The backend to switch to. This can either be one of the standard
1127 backend names, which are case-insensitive:
1129 - interactive backends:
1130 GTK3Agg, GTK3Cairo, GTK4Agg, GTK4Cairo, MacOSX, nbAgg, QtAgg,
1131 QtCairo, TkAgg, TkCairo, WebAgg, WX, WXAgg, WXCairo, Qt5Agg, Qt5Cairo
1133 - non-interactive backends:
1134 agg, cairo, pdf, pgf, ps, svg, template
1136 or a string of the form: ``module://my.module.name``.
1138 Switching to an interactive backend is not possible if an unrelated
1139 event loop has already been started (e.g., switching to GTK3Agg if a
1140 TkAgg window has already been opened). Switching to a non-interactive
1141 backend is always possible.
1143 force : bool, default: True
1144 If True (the default), raise an `ImportError` if the backend cannot be
1145 set up (either because it fails to import, or because an incompatible
1146 GUI interactive framework is already running); if False, silently
1147 ignore the failure.
1149 See Also
1150 --------
1151 :ref:`backends`
1152 matplotlib.get_backend
1153 """
1154 name = validate_backend(backend)
1155 # don't (prematurely) resolve the "auto" backend setting
1156 if rcParams._get_backend_or_none() == name:
1157 # Nothing to do if the requested backend is already set
1158 pass
1159 else:
1160 # if pyplot is not already imported, do not import it. Doing
1161 # so may trigger a `plt.switch_backend` to the _default_ backend
1162 # before we get a chance to change to the one the user just requested
1163 plt = sys.modules.get('matplotlib.pyplot')
1164 # if pyplot is imported, then try to change backends
1165 if plt is not None:
1166 try:
1167 # we need this import check here to re-raise if the
1168 # user does not have the libraries to support their
1169 # chosen backend installed.
1170 plt.switch_backend(name)
1171 except ImportError:
1172 if force:
1173 raise
1174 # if we have not imported pyplot, then we can set the rcParam
1175 # value which will be respected when the user finally imports
1176 # pyplot
1177 else:
1178 rcParams['backend'] = backend
1179 # if the user has asked for a given backend, do not helpfully
1180 # fallback
1181 rcParams['backend_fallback'] = False
1184if os.environ.get('MPLBACKEND'):
1185 rcParams['backend'] = os.environ.get('MPLBACKEND')
1188def get_backend():
1189 """
1190 Return the name of the current backend.
1192 See Also
1193 --------
1194 matplotlib.use
1195 """
1196 return rcParams['backend']
1199def interactive(b):
1200 """
1201 Set whether to redraw after every plotting command (e.g. `.pyplot.xlabel`).
1202 """
1203 rcParams['interactive'] = b
1206def is_interactive():
1207 """
1208 Return whether to redraw after every plotting command.
1210 .. note::
1212 This function is only intended for use in backends. End users should
1213 use `.pyplot.isinteractive` instead.
1214 """
1215 return rcParams['interactive']
1218default_test_modules = [
1219 'matplotlib.tests',
1220 'mpl_toolkits.tests',
1221]
1224def _init_tests():
1225 # The version of FreeType to install locally for running the
1226 # tests. This must match the value in `setupext.py`
1227 LOCAL_FREETYPE_VERSION = '2.6.1'
1229 from matplotlib import ft2font
1230 if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or
1231 ft2font.__freetype_build_type__ != 'local'):
1232 _log.warning(
1233 f"Matplotlib is not built with the correct FreeType version to "
1234 f"run tests. Rebuild without setting system_freetype=1 in "
1235 f"mplsetup.cfg. Expect many image comparison failures below. "
1236 f"Expected freetype version {LOCAL_FREETYPE_VERSION}. "
1237 f"Found freetype version {ft2font.__freetype_version__}. "
1238 "Freetype build type is {}local".format(
1239 "" if ft2font.__freetype_build_type__ == 'local' else "not "))
1242@_api.deprecated("3.5", alternative='pytest')
1243def test(verbosity=None, coverage=False, **kwargs):
1244 """Run the matplotlib test suite."""
1246 try:
1247 import pytest
1248 except ImportError:
1249 print("matplotlib.test requires pytest to run.")
1250 return -1
1252 if not os.path.isdir(os.path.join(os.path.dirname(__file__), 'tests')):
1253 print("Matplotlib test data is not installed")
1254 return -1
1256 old_backend = get_backend()
1257 try:
1258 use('agg')
1260 args = kwargs.pop('argv', [])
1261 provide_default_modules = True
1262 use_pyargs = True
1263 for arg in args:
1264 if any(arg.startswith(module_path)
1265 for module_path in default_test_modules):
1266 provide_default_modules = False
1267 break
1268 if os.path.exists(arg):
1269 provide_default_modules = False
1270 use_pyargs = False
1271 break
1272 if use_pyargs:
1273 args += ['--pyargs']
1274 if provide_default_modules:
1275 args += default_test_modules
1277 if coverage:
1278 args += ['--cov']
1280 if verbosity:
1281 args += ['-' + 'v' * verbosity]
1283 retcode = pytest.main(args, **kwargs)
1284 finally:
1285 if old_backend.lower() != 'agg':
1286 use(old_backend)
1288 return retcode
1291test.__test__ = False # pytest: this function is not a test
1294def _replacer(data, value):
1295 """
1296 Either returns ``data[value]`` or passes ``data`` back, converts either to
1297 a sequence.
1298 """
1299 try:
1300 # if key isn't a string don't bother
1301 if isinstance(value, str):
1302 # try to use __getitem__
1303 value = data[value]
1304 except Exception:
1305 # key does not exist, silently fall back to key
1306 pass
1307 return sanitize_sequence(value)
1310def _label_from_arg(y, default_name):
1311 try:
1312 return y.name
1313 except AttributeError:
1314 if isinstance(default_name, str):
1315 return default_name
1316 return None
1319def _add_data_doc(docstring, replace_names):
1320 """
1321 Add documentation for a *data* field to the given docstring.
1323 Parameters
1324 ----------
1325 docstring : str
1326 The input docstring.
1327 replace_names : list of str or None
1328 The list of parameter names which arguments should be replaced by
1329 ``data[name]`` (if ``data[name]`` does not throw an exception). If
1330 None, replacement is attempted for all arguments.
1332 Returns
1333 -------
1334 str
1335 The augmented docstring.
1336 """
1337 if (docstring is None
1338 or replace_names is not None and len(replace_names) == 0):
1339 return docstring
1340 docstring = inspect.cleandoc(docstring)
1342 data_doc = ("""\
1343 If given, all parameters also accept a string ``s``, which is
1344 interpreted as ``data[s]`` (unless this raises an exception)."""
1345 if replace_names is None else f"""\
1346 \
1347 If given, the following parameters also accept a string ``s``, which is
1348 interpreted as ``data[s]`` (unless this raises an exception):
1350 {', '.join(map('*{}*'.format, replace_names))}""")
1351 # using string replacement instead of formatting has the advantages
1352 # 1) simpler indent handling
1353 # 2) prevent problems with formatting characters '{', '%' in the docstring
1354 if _log.level <= logging.DEBUG:
1355 # test_data_parameter_replacement() tests against these log messages
1356 # make sure to keep message and test in sync
1357 if "data : indexable object, optional" not in docstring:
1358 _log.debug("data parameter docstring error: no data parameter")
1359 if 'DATA_PARAMETER_PLACEHOLDER' not in docstring:
1360 _log.debug("data parameter docstring error: missing placeholder")
1361 return docstring.replace(' DATA_PARAMETER_PLACEHOLDER', data_doc)
1364def _preprocess_data(func=None, *, replace_names=None, label_namer=None):
1365 """
1366 A decorator to add a 'data' kwarg to a function.
1368 When applied::
1370 @_preprocess_data()
1371 def func(ax, *args, **kwargs): ...
1373 the signature is modified to ``decorated(ax, *args, data=None, **kwargs)``
1374 with the following behavior:
1376 - if called with ``data=None``, forward the other arguments to ``func``;
1377 - otherwise, *data* must be a mapping; for any argument passed in as a
1378 string ``name``, replace the argument by ``data[name]`` (if this does not
1379 throw an exception), then forward the arguments to ``func``.
1381 In either case, any argument that is a `MappingView` is also converted to a
1382 list.
1384 Parameters
1385 ----------
1386 replace_names : list of str or None, default: None
1387 The list of parameter names for which lookup into *data* should be
1388 attempted. If None, replacement is attempted for all arguments.
1389 label_namer : str, default: None
1390 If set e.g. to "namer" (which must be a kwarg in the function's
1391 signature -- not as ``**kwargs``), if the *namer* argument passed in is
1392 a (string) key of *data* and no *label* kwarg is passed, then use the
1393 (string) value of the *namer* as *label*. ::
1395 @_preprocess_data(label_namer="foo")
1396 def func(foo, label=None): ...
1398 func("key", data={"key": value})
1399 # is equivalent to
1400 func.__wrapped__(value, label="key")
1401 """
1403 if func is None: # Return the actual decorator.
1404 return functools.partial(
1405 _preprocess_data,
1406 replace_names=replace_names, label_namer=label_namer)
1408 sig = inspect.signature(func)
1409 varargs_name = None
1410 varkwargs_name = None
1411 arg_names = []
1412 params = list(sig.parameters.values())
1413 for p in params:
1414 if p.kind is Parameter.VAR_POSITIONAL:
1415 varargs_name = p.name
1416 elif p.kind is Parameter.VAR_KEYWORD:
1417 varkwargs_name = p.name
1418 else:
1419 arg_names.append(p.name)
1420 data_param = Parameter("data", Parameter.KEYWORD_ONLY, default=None)
1421 if varkwargs_name:
1422 params.insert(-1, data_param)
1423 else:
1424 params.append(data_param)
1425 new_sig = sig.replace(parameters=params)
1426 arg_names = arg_names[1:] # remove the first "ax" / self arg
1428 assert {*arg_names}.issuperset(replace_names or []) or varkwargs_name, (
1429 "Matplotlib internal error: invalid replace_names ({!r}) for {!r}"
1430 .format(replace_names, func.__name__))
1431 assert label_namer is None or label_namer in arg_names, (
1432 "Matplotlib internal error: invalid label_namer ({!r}) for {!r}"
1433 .format(label_namer, func.__name__))
1435 @functools.wraps(func)
1436 def inner(ax, *args, data=None, **kwargs):
1437 if data is None:
1438 return func(ax, *map(sanitize_sequence, args), **kwargs)
1440 bound = new_sig.bind(ax, *args, **kwargs)
1441 auto_label = (bound.arguments.get(label_namer)
1442 or bound.kwargs.get(label_namer))
1444 for k, v in bound.arguments.items():
1445 if k == varkwargs_name:
1446 for k1, v1 in v.items():
1447 if replace_names is None or k1 in replace_names:
1448 v[k1] = _replacer(data, v1)
1449 elif k == varargs_name:
1450 if replace_names is None:
1451 bound.arguments[k] = tuple(_replacer(data, v1) for v1 in v)
1452 else:
1453 if replace_names is None or k in replace_names:
1454 bound.arguments[k] = _replacer(data, v)
1456 new_args = bound.args
1457 new_kwargs = bound.kwargs
1459 args_and_kwargs = {**bound.arguments, **bound.kwargs}
1460 if label_namer and "label" not in args_and_kwargs:
1461 new_kwargs["label"] = _label_from_arg(
1462 args_and_kwargs.get(label_namer), auto_label)
1464 return func(*new_args, **new_kwargs)
1466 inner.__doc__ = _add_data_doc(inner.__doc__, replace_names)
1467 inner.__signature__ = new_sig
1468 return inner
1471_log.debug('interactive is %s', is_interactive())
1472_log.debug('platform is %s', sys.platform)
1475# workaround: we must defer colormaps import to after loading rcParams, because
1476# colormap creation depends on rcParams
1477from matplotlib.cm import _colormaps as colormaps
1478from matplotlib.colors import _color_sequences as color_sequences