12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346 |
- """
- The rcsetup module contains the validation code for customization using
- Matplotlib's rc settings.
- Each rc setting is assigned a function used to validate any attempted changes
- to that setting. The validation functions are defined in the rcsetup module,
- and are used to construct the rcParams global object which stores the settings
- and is referenced throughout Matplotlib.
- The default values of the rc settings are set in the default matplotlibrc file.
- Any additions or deletions to the parameter set listed here should also be
- propagated to the :file:`lib/matplotlib/mpl-data/matplotlibrc` in Matplotlib's
- root source directory.
- """
- import ast
- from functools import lru_cache, reduce
- from numbers import Real
- import operator
- import os
- import re
- import numpy as np
- from matplotlib import _api, cbook
- from matplotlib.cbook import ls_mapper
- from matplotlib.colors import Colormap, is_color_like
- from matplotlib._fontconfig_pattern import parse_fontconfig_pattern
- from matplotlib._enums import JoinStyle, CapStyle
- # Don't let the original cycler collide with our validating cycler
- from cycler import Cycler, cycler as ccycler
- # The capitalized forms are needed for ipython at present; this may
- # change for later versions.
- interactive_bk = [
- 'GTK3Agg', 'GTK3Cairo', 'GTK4Agg', 'GTK4Cairo',
- 'MacOSX',
- 'nbAgg',
- 'QtAgg', 'QtCairo', 'Qt5Agg', 'Qt5Cairo',
- 'TkAgg', 'TkCairo',
- 'WebAgg',
- 'WX', 'WXAgg', 'WXCairo',
- ]
- non_interactive_bk = ['agg', 'cairo',
- 'pdf', 'pgf', 'ps', 'svg', 'template']
- all_backends = interactive_bk + non_interactive_bk
- class ValidateInStrings:
- def __init__(self, key, valid, ignorecase=False, *,
- _deprecated_since=None):
- """*valid* is a list of legal strings."""
- self.key = key
- self.ignorecase = ignorecase
- self._deprecated_since = _deprecated_since
- def func(s):
- if ignorecase:
- return s.lower()
- else:
- return s
- self.valid = {func(k): k for k in valid}
- def __call__(self, s):
- if self._deprecated_since:
- name, = (k for k, v in globals().items() if v is self)
- _api.warn_deprecated(
- self._deprecated_since, name=name, obj_type="function")
- if self.ignorecase and isinstance(s, str):
- s = s.lower()
- if s in self.valid:
- return self.valid[s]
- msg = (f"{s!r} is not a valid value for {self.key}; supported values "
- f"are {[*self.valid.values()]}")
- if (isinstance(s, str)
- and (s.startswith('"') and s.endswith('"')
- or s.startswith("'") and s.endswith("'"))
- and s[1:-1] in self.valid):
- msg += "; remove quotes surrounding your string"
- raise ValueError(msg)
- @lru_cache
- def _listify_validator(scalar_validator, allow_stringlist=False, *,
- n=None, doc=None):
- def f(s):
- if isinstance(s, str):
- try:
- val = [scalar_validator(v.strip()) for v in s.split(',')
- if v.strip()]
- except Exception:
- if allow_stringlist:
- # Sometimes, a list of colors might be a single string
- # of single-letter colornames. So give that a shot.
- val = [scalar_validator(v.strip()) for v in s if v.strip()]
- else:
- raise
- # Allow any ordered sequence type -- generators, np.ndarray, pd.Series
- # -- but not sets, whose iteration order is non-deterministic.
- elif np.iterable(s) and not isinstance(s, (set, frozenset)):
- # The condition on this list comprehension will preserve the
- # behavior of filtering out any empty strings (behavior was
- # from the original validate_stringlist()), while allowing
- # any non-string/text scalar values such as numbers and arrays.
- val = [scalar_validator(v) for v in s
- if not isinstance(v, str) or v]
- else:
- raise ValueError(
- f"Expected str or other non-set iterable, but got {s}")
- if n is not None and len(val) != n:
- raise ValueError(
- f"Expected {n} values, but there are {len(val)} values in {s}")
- return val
- try:
- f.__name__ = f"{scalar_validator.__name__}list"
- except AttributeError: # class instance.
- f.__name__ = f"{type(scalar_validator).__name__}List"
- f.__qualname__ = f.__qualname__.rsplit(".", 1)[0] + "." + f.__name__
- f.__doc__ = doc if doc is not None else scalar_validator.__doc__
- return f
- def validate_any(s):
- return s
- validate_anylist = _listify_validator(validate_any)
- def _validate_date(s):
- try:
- np.datetime64(s)
- return s
- except ValueError:
- raise ValueError(
- f'{s!r} should be a string that can be parsed by numpy.datetime64')
- def validate_bool(b):
- """Convert b to ``bool`` or raise."""
- if isinstance(b, str):
- b = b.lower()
- if b in ('t', 'y', 'yes', 'on', 'true', '1', 1, True):
- return True
- elif b in ('f', 'n', 'no', 'off', 'false', '0', 0, False):
- return False
- else:
- raise ValueError(f'Cannot convert {b!r} to bool')
- def validate_axisbelow(s):
- try:
- return validate_bool(s)
- except ValueError:
- if isinstance(s, str):
- if s == 'line':
- return 'line'
- raise ValueError(f'{s!r} cannot be interpreted as'
- ' True, False, or "line"')
- def validate_dpi(s):
- """Confirm s is string 'figure' or convert s to float or raise."""
- if s == 'figure':
- return s
- try:
- return float(s)
- except ValueError as e:
- raise ValueError(f'{s!r} is not string "figure" and '
- f'could not convert {s!r} to float') from e
- def _make_type_validator(cls, *, allow_none=False):
- """
- Return a validator that converts inputs to *cls* or raises (and possibly
- allows ``None`` as well).
- """
- def validator(s):
- if (allow_none and
- (s is None or isinstance(s, str) and s.lower() == "none")):
- return None
- if cls is str and not isinstance(s, str):
- raise ValueError(f'Could not convert {s!r} to str')
- try:
- return cls(s)
- except (TypeError, ValueError) as e:
- raise ValueError(
- f'Could not convert {s!r} to {cls.__name__}') from e
- validator.__name__ = f"validate_{cls.__name__}"
- if allow_none:
- validator.__name__ += "_or_None"
- validator.__qualname__ = (
- validator.__qualname__.rsplit(".", 1)[0] + "." + validator.__name__)
- return validator
- validate_string = _make_type_validator(str)
- validate_string_or_None = _make_type_validator(str, allow_none=True)
- validate_stringlist = _listify_validator(
- validate_string, doc='return a list of strings')
- validate_int = _make_type_validator(int)
- validate_int_or_None = _make_type_validator(int, allow_none=True)
- validate_float = _make_type_validator(float)
- validate_float_or_None = _make_type_validator(float, allow_none=True)
- validate_floatlist = _listify_validator(
- validate_float, doc='return a list of floats')
- def _validate_pathlike(s):
- if isinstance(s, (str, os.PathLike)):
- # Store value as str because savefig.directory needs to distinguish
- # between "" (cwd) and "." (cwd, but gets updated by user selections).
- return os.fsdecode(s)
- else:
- return validate_string(s)
- def validate_fonttype(s):
- """
- Confirm that this is a Postscript or PDF font type that we know how to
- convert to.
- """
- fonttypes = {'type3': 3,
- 'truetype': 42}
- try:
- fonttype = validate_int(s)
- except ValueError:
- try:
- return fonttypes[s.lower()]
- except KeyError as e:
- raise ValueError('Supported Postscript/PDF font types are %s'
- % list(fonttypes)) from e
- else:
- if fonttype not in fonttypes.values():
- raise ValueError(
- 'Supported Postscript/PDF font types are %s' %
- list(fonttypes.values()))
- return fonttype
- _validate_standard_backends = ValidateInStrings(
- 'backend', all_backends, ignorecase=True)
- _auto_backend_sentinel = object()
- def validate_backend(s):
- backend = (
- s if s is _auto_backend_sentinel or s.startswith("module://")
- else _validate_standard_backends(s))
- return backend
- def _validate_toolbar(s):
- s = ValidateInStrings(
- 'toolbar', ['None', 'toolbar2', 'toolmanager'], ignorecase=True)(s)
- if s == 'toolmanager':
- _api.warn_external(
- "Treat the new Tool classes introduced in v1.5 as experimental "
- "for now; the API and rcParam may change in future versions.")
- return s
- def validate_color_or_inherit(s):
- """Return a valid color arg."""
- if cbook._str_equal(s, 'inherit'):
- return s
- return validate_color(s)
- def validate_color_or_auto(s):
- if cbook._str_equal(s, 'auto'):
- return s
- return validate_color(s)
- def validate_color_for_prop_cycle(s):
- # N-th color cycle syntax can't go into the color cycle.
- if isinstance(s, str) and re.match("^C[0-9]$", s):
- raise ValueError(f"Cannot put cycle reference ({s!r}) in prop_cycler")
- return validate_color(s)
- def _validate_color_or_linecolor(s):
- if cbook._str_equal(s, 'linecolor'):
- return s
- elif cbook._str_equal(s, 'mfc') or cbook._str_equal(s, 'markerfacecolor'):
- return 'markerfacecolor'
- elif cbook._str_equal(s, 'mec') or cbook._str_equal(s, 'markeredgecolor'):
- return 'markeredgecolor'
- elif s is None:
- return None
- elif isinstance(s, str) and len(s) == 6 or len(s) == 8:
- stmp = '#' + s
- if is_color_like(stmp):
- return stmp
- if s.lower() == 'none':
- return None
- elif is_color_like(s):
- return s
- raise ValueError(f'{s!r} does not look like a color arg')
- def validate_color(s):
- """Return a valid color arg."""
- if isinstance(s, str):
- if s.lower() == 'none':
- return 'none'
- if len(s) == 6 or len(s) == 8:
- stmp = '#' + s
- if is_color_like(stmp):
- return stmp
- if is_color_like(s):
- return s
- # If it is still valid, it must be a tuple (as a string from matplotlibrc).
- try:
- color = ast.literal_eval(s)
- except (SyntaxError, ValueError):
- pass
- else:
- if is_color_like(color):
- return color
- raise ValueError(f'{s!r} does not look like a color arg')
- validate_colorlist = _listify_validator(
- validate_color, allow_stringlist=True, doc='return a list of colorspecs')
- def _validate_cmap(s):
- _api.check_isinstance((str, Colormap), cmap=s)
- return s
- def validate_aspect(s):
- if s in ('auto', 'equal'):
- return s
- try:
- return float(s)
- except ValueError as e:
- raise ValueError('not a valid aspect specification') from e
- def validate_fontsize_None(s):
- if s is None or s == 'None':
- return None
- else:
- return validate_fontsize(s)
- def validate_fontsize(s):
- fontsizes = ['xx-small', 'x-small', 'small', 'medium', 'large',
- 'x-large', 'xx-large', 'smaller', 'larger']
- if isinstance(s, str):
- s = s.lower()
- if s in fontsizes:
- return s
- try:
- return float(s)
- except ValueError as e:
- raise ValueError("%s is not a valid font size. Valid font sizes "
- "are %s." % (s, ", ".join(fontsizes))) from e
- validate_fontsizelist = _listify_validator(validate_fontsize)
- def validate_fontweight(s):
- weights = [
- 'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman',
- 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black']
- # Note: Historically, weights have been case-sensitive in Matplotlib
- if s in weights:
- return s
- try:
- return int(s)
- except (ValueError, TypeError) as e:
- raise ValueError(f'{s} is not a valid font weight.') from e
- def validate_fontstretch(s):
- stretchvalues = [
- 'ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed',
- 'normal', 'semi-expanded', 'expanded', 'extra-expanded',
- 'ultra-expanded']
- # Note: Historically, stretchvalues have been case-sensitive in Matplotlib
- if s in stretchvalues:
- return s
- try:
- return int(s)
- except (ValueError, TypeError) as e:
- raise ValueError(f'{s} is not a valid font stretch.') from e
- def validate_font_properties(s):
- parse_fontconfig_pattern(s)
- return s
- def _validate_mathtext_fallback(s):
- _fallback_fonts = ['cm', 'stix', 'stixsans']
- if isinstance(s, str):
- s = s.lower()
- if s is None or s == 'none':
- return None
- elif s.lower() in _fallback_fonts:
- return s
- else:
- raise ValueError(
- f"{s} is not a valid fallback font name. Valid fallback font "
- f"names are {','.join(_fallback_fonts)}. Passing 'None' will turn "
- "fallback off.")
- def validate_whiskers(s):
- try:
- return _listify_validator(validate_float, n=2)(s)
- except (TypeError, ValueError):
- try:
- return float(s)
- except ValueError as e:
- raise ValueError("Not a valid whisker value [float, "
- "(float, float)]") from e
- def validate_ps_distiller(s):
- if isinstance(s, str):
- s = s.lower()
- if s in ('none', None, 'false', False):
- return None
- else:
- return ValidateInStrings('ps.usedistiller', ['ghostscript', 'xpdf'])(s)
- def _validate_papersize(s):
- # Re-inline this validator when the 'auto' deprecation expires.
- s = ValidateInStrings("ps.papersize",
- ["figure", "auto", "letter", "legal", "ledger",
- *[f"{ab}{i}" for ab in "ab" for i in range(11)]],
- ignorecase=True)(s)
- if s == "auto":
- _api.warn_deprecated("3.8", name="ps.papersize='auto'",
- addendum="Pass an explicit paper type, figure, or omit "
- "the *ps.papersize* rcParam entirely.")
- return s
- # A validator dedicated to the named line styles, based on the items in
- # ls_mapper, and a list of possible strings read from Line2D.set_linestyle
- _validate_named_linestyle = ValidateInStrings(
- 'linestyle',
- [*ls_mapper.keys(), *ls_mapper.values(), 'None', 'none', ' ', ''],
- ignorecase=True)
- def _validate_linestyle(ls):
- """
- A validator for all possible line styles, the named ones *and*
- the on-off ink sequences.
- """
- if isinstance(ls, str):
- try: # Look first for a valid named line style, like '--' or 'solid'.
- return _validate_named_linestyle(ls)
- except ValueError:
- pass
- try:
- ls = ast.literal_eval(ls) # Parsing matplotlibrc.
- except (SyntaxError, ValueError):
- pass # Will error with the ValueError at the end.
- def _is_iterable_not_string_like(x):
- # Explicitly exclude bytes/bytearrays so that they are not
- # nonsensically interpreted as sequences of numbers (codepoints).
- return np.iterable(x) and not isinstance(x, (str, bytes, bytearray))
- if _is_iterable_not_string_like(ls):
- if len(ls) == 2 and _is_iterable_not_string_like(ls[1]):
- # (offset, (on, off, on, off, ...))
- offset, onoff = ls
- else:
- # For backcompat: (on, off, on, off, ...); the offset is implicit.
- offset = 0
- onoff = ls
- if (isinstance(offset, Real)
- and len(onoff) % 2 == 0
- and all(isinstance(elem, Real) for elem in onoff)):
- return (offset, onoff)
- raise ValueError(f"linestyle {ls!r} is not a valid on-off ink sequence.")
- validate_fillstyle = ValidateInStrings(
- 'markers.fillstyle', ['full', 'left', 'right', 'bottom', 'top', 'none'])
- validate_fillstylelist = _listify_validator(validate_fillstyle)
- def validate_markevery(s):
- """
- Validate the markevery property of a Line2D object.
- Parameters
- ----------
- s : None, int, (int, int), slice, float, (float, float), or list[int]
- Returns
- -------
- None, int, (int, int), slice, float, (float, float), or list[int]
- """
- # Validate s against type slice float int and None
- if isinstance(s, (slice, float, int, type(None))):
- return s
- # Validate s against type tuple
- if isinstance(s, tuple):
- if (len(s) == 2
- and (all(isinstance(e, int) for e in s)
- or all(isinstance(e, float) for e in s))):
- return s
- else:
- raise TypeError(
- "'markevery' tuple must be pair of ints or of floats")
- # Validate s against type list
- if isinstance(s, list):
- if all(isinstance(e, int) for e in s):
- return s
- else:
- raise TypeError(
- "'markevery' list must have all elements of type int")
- raise TypeError("'markevery' is of an invalid type")
- validate_markeverylist = _listify_validator(validate_markevery)
- def validate_bbox(s):
- if isinstance(s, str):
- s = s.lower()
- if s == 'tight':
- return s
- if s == 'standard':
- return None
- raise ValueError("bbox should be 'tight' or 'standard'")
- elif s is not None:
- # Backwards compatibility. None is equivalent to 'standard'.
- raise ValueError("bbox should be 'tight' or 'standard'")
- return s
- def validate_sketch(s):
- if isinstance(s, str):
- s = s.lower()
- if s == 'none' or s is None:
- return None
- try:
- return tuple(_listify_validator(validate_float, n=3)(s))
- except ValueError:
- raise ValueError("Expected a (scale, length, randomness) triplet")
- def _validate_greaterthan_minushalf(s):
- s = validate_float(s)
- if s > -0.5:
- return s
- else:
- raise RuntimeError(f'Value must be >-0.5; got {s}')
- def _validate_greaterequal0_lessequal1(s):
- s = validate_float(s)
- if 0 <= s <= 1:
- return s
- else:
- raise RuntimeError(f'Value must be >=0 and <=1; got {s}')
- def _validate_int_greaterequal0(s):
- s = validate_int(s)
- if s >= 0:
- return s
- else:
- raise RuntimeError(f'Value must be >=0; got {s}')
- def validate_hatch(s):
- r"""
- Validate a hatch pattern.
- A hatch pattern string can have any sequence of the following
- characters: ``\ / | - + * . x o O``.
- """
- if not isinstance(s, str):
- raise ValueError("Hatch pattern must be a string")
- _api.check_isinstance(str, hatch_pattern=s)
- unknown = set(s) - {'\\', '/', '|', '-', '+', '*', '.', 'x', 'o', 'O'}
- if unknown:
- raise ValueError("Unknown hatch symbol(s): %s" % list(unknown))
- return s
- validate_hatchlist = _listify_validator(validate_hatch)
- validate_dashlist = _listify_validator(validate_floatlist)
- def _validate_minor_tick_ndivs(n):
- """
- Validate ndiv parameter related to the minor ticks.
- It controls the number of minor ticks to be placed between
- two major ticks.
- """
- if isinstance(n, str) and n.lower() == 'auto':
- return n
- try:
- n = _validate_int_greaterequal0(n)
- return n
- except (RuntimeError, ValueError):
- pass
- raise ValueError("'tick.minor.ndivs' must be 'auto' or non-negative int")
- _prop_validators = {
- 'color': _listify_validator(validate_color_for_prop_cycle,
- allow_stringlist=True),
- 'linewidth': validate_floatlist,
- 'linestyle': _listify_validator(_validate_linestyle),
- 'facecolor': validate_colorlist,
- 'edgecolor': validate_colorlist,
- 'joinstyle': _listify_validator(JoinStyle),
- 'capstyle': _listify_validator(CapStyle),
- 'fillstyle': validate_fillstylelist,
- 'markerfacecolor': validate_colorlist,
- 'markersize': validate_floatlist,
- 'markeredgewidth': validate_floatlist,
- 'markeredgecolor': validate_colorlist,
- 'markevery': validate_markeverylist,
- 'alpha': validate_floatlist,
- 'marker': validate_stringlist,
- 'hatch': validate_hatchlist,
- 'dashes': validate_dashlist,
- }
- _prop_aliases = {
- 'c': 'color',
- 'lw': 'linewidth',
- 'ls': 'linestyle',
- 'fc': 'facecolor',
- 'ec': 'edgecolor',
- 'mfc': 'markerfacecolor',
- 'mec': 'markeredgecolor',
- 'mew': 'markeredgewidth',
- 'ms': 'markersize',
- }
- def cycler(*args, **kwargs):
- """
- Create a `~cycler.Cycler` object much like :func:`cycler.cycler`,
- but includes input validation.
- Call signatures::
- cycler(cycler)
- cycler(label=values[, label2=values2[, ...]])
- cycler(label, values)
- Form 1 copies a given `~cycler.Cycler` object.
- Form 2 creates a `~cycler.Cycler` which cycles over one or more
- properties simultaneously. If multiple properties are given, their
- value lists must have the same length.
- Form 3 creates a `~cycler.Cycler` for a single property. This form
- exists for compatibility with the original cycler. Its use is
- discouraged in favor of the kwarg form, i.e. ``cycler(label=values)``.
- Parameters
- ----------
- cycler : Cycler
- Copy constructor for Cycler.
- label : str
- The property key. Must be a valid `.Artist` property.
- For example, 'color' or 'linestyle'. Aliases are allowed,
- such as 'c' for 'color' and 'lw' for 'linewidth'.
- values : iterable
- Finite-length iterable of the property values. These values
- are validated and will raise a ValueError if invalid.
- Returns
- -------
- Cycler
- A new :class:`~cycler.Cycler` for the given properties.
- Examples
- --------
- Creating a cycler for a single property:
- >>> c = cycler(color=['red', 'green', 'blue'])
- Creating a cycler for simultaneously cycling over multiple properties
- (e.g. red circle, green plus, blue cross):
- >>> c = cycler(color=['red', 'green', 'blue'],
- ... marker=['o', '+', 'x'])
- """
- if args and kwargs:
- raise TypeError("cycler() can only accept positional OR keyword "
- "arguments -- not both.")
- elif not args and not kwargs:
- raise TypeError("cycler() must have positional OR keyword arguments")
- if len(args) == 1:
- if not isinstance(args[0], Cycler):
- raise TypeError("If only one positional argument given, it must "
- "be a Cycler instance.")
- return validate_cycler(args[0])
- elif len(args) == 2:
- pairs = [(args[0], args[1])]
- elif len(args) > 2:
- raise _api.nargs_error('cycler', '0-2', len(args))
- else:
- pairs = kwargs.items()
- validated = []
- for prop, vals in pairs:
- norm_prop = _prop_aliases.get(prop, prop)
- validator = _prop_validators.get(norm_prop, None)
- if validator is None:
- raise TypeError("Unknown artist property: %s" % prop)
- vals = validator(vals)
- # We will normalize the property names as well to reduce
- # the amount of alias handling code elsewhere.
- validated.append((norm_prop, vals))
- return reduce(operator.add, (ccycler(k, v) for k, v in validated))
- class _DunderChecker(ast.NodeVisitor):
- def visit_Attribute(self, node):
- if node.attr.startswith("__") and node.attr.endswith("__"):
- raise ValueError("cycler strings with dunders are forbidden")
- self.generic_visit(node)
- # A validator dedicated to the named legend loc
- _validate_named_legend_loc = ValidateInStrings(
- 'legend.loc',
- [
- "best",
- "upper right", "upper left", "lower left", "lower right", "right",
- "center left", "center right", "lower center", "upper center",
- "center"],
- ignorecase=True)
- def _validate_legend_loc(loc):
- """
- Confirm that loc is a type which rc.Params["legend.loc"] supports.
- .. versionadded:: 3.8
- Parameters
- ----------
- loc : str | int | (float, float) | str((float, float))
- The location of the legend.
- Returns
- -------
- loc : str | int | (float, float) or raise ValueError exception
- The location of the legend.
- """
- if isinstance(loc, str):
- try:
- return _validate_named_legend_loc(loc)
- except ValueError:
- pass
- try:
- loc = ast.literal_eval(loc)
- except (SyntaxError, ValueError):
- pass
- if isinstance(loc, int):
- if 0 <= loc <= 10:
- return loc
- if isinstance(loc, tuple):
- if len(loc) == 2 and all(isinstance(e, Real) for e in loc):
- return loc
- raise ValueError(f"{loc} is not a valid legend location.")
- def validate_cycler(s):
- """Return a Cycler object from a string repr or the object itself."""
- if isinstance(s, str):
- # TODO: We might want to rethink this...
- # While I think I have it quite locked down, it is execution of
- # arbitrary code without sanitation.
- # Combine this with the possibility that rcparams might come from the
- # internet (future plans), this could be downright dangerous.
- # I locked it down by only having the 'cycler()' function available.
- # UPDATE: Partly plugging a security hole.
- # I really should have read this:
- # https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
- # We should replace this eval with a combo of PyParsing and
- # ast.literal_eval()
- try:
- _DunderChecker().visit(ast.parse(s))
- s = eval(s, {'cycler': cycler, '__builtins__': {}})
- except BaseException as e:
- raise ValueError(f"{s!r} is not a valid cycler construction: {e}"
- ) from e
- # Should make sure what comes from the above eval()
- # is a Cycler object.
- if isinstance(s, Cycler):
- cycler_inst = s
- else:
- raise ValueError(f"Object is not a string or Cycler instance: {s!r}")
- unknowns = cycler_inst.keys - (set(_prop_validators) | set(_prop_aliases))
- if unknowns:
- raise ValueError("Unknown artist properties: %s" % unknowns)
- # Not a full validation, but it'll at least normalize property names
- # A fuller validation would require v0.10 of cycler.
- checker = set()
- for prop in cycler_inst.keys:
- norm_prop = _prop_aliases.get(prop, prop)
- if norm_prop != prop and norm_prop in cycler_inst.keys:
- raise ValueError(f"Cannot specify both {norm_prop!r} and alias "
- f"{prop!r} in the same prop_cycle")
- if norm_prop in checker:
- raise ValueError(f"Another property was already aliased to "
- f"{norm_prop!r}. Collision normalizing {prop!r}.")
- checker.update([norm_prop])
- # This is just an extra-careful check, just in case there is some
- # edge-case I haven't thought of.
- assert len(checker) == len(cycler_inst.keys)
- # Now, it should be safe to mutate this cycler
- for prop in cycler_inst.keys:
- norm_prop = _prop_aliases.get(prop, prop)
- cycler_inst.change_key(prop, norm_prop)
- for key, vals in cycler_inst.by_key().items():
- _prop_validators[key](vals)
- return cycler_inst
- def validate_hist_bins(s):
- valid_strs = ["auto", "sturges", "fd", "doane", "scott", "rice", "sqrt"]
- if isinstance(s, str) and s in valid_strs:
- return s
- try:
- return int(s)
- except (TypeError, ValueError):
- pass
- try:
- return validate_floatlist(s)
- except ValueError:
- pass
- raise ValueError(f"'hist.bins' must be one of {valid_strs}, an int or"
- " a sequence of floats")
- class _ignorecase(list):
- """A marker class indicating that a list-of-str is case-insensitive."""
- def _convert_validator_spec(key, conv):
- if isinstance(conv, list):
- ignorecase = isinstance(conv, _ignorecase)
- return ValidateInStrings(key, conv, ignorecase=ignorecase)
- else:
- return conv
- # Mapping of rcParams to validators.
- # Converters given as lists or _ignorecase are converted to ValidateInStrings
- # immediately below.
- # The rcParams defaults are defined in lib/matplotlib/mpl-data/matplotlibrc, which
- # gets copied to matplotlib/mpl-data/matplotlibrc by the setup script.
- _validators = {
- "backend": validate_backend,
- "backend_fallback": validate_bool,
- "figure.hooks": validate_stringlist,
- "toolbar": _validate_toolbar,
- "interactive": validate_bool,
- "timezone": validate_string,
- "webagg.port": validate_int,
- "webagg.address": validate_string,
- "webagg.open_in_browser": validate_bool,
- "webagg.port_retries": validate_int,
- # line props
- "lines.linewidth": validate_float, # line width in points
- "lines.linestyle": _validate_linestyle, # solid line
- "lines.color": validate_color, # first color in color cycle
- "lines.marker": validate_string, # marker name
- "lines.markerfacecolor": validate_color_or_auto, # default color
- "lines.markeredgecolor": validate_color_or_auto, # default color
- "lines.markeredgewidth": validate_float,
- "lines.markersize": validate_float, # markersize, in points
- "lines.antialiased": validate_bool, # antialiased (no jaggies)
- "lines.dash_joinstyle": JoinStyle,
- "lines.solid_joinstyle": JoinStyle,
- "lines.dash_capstyle": CapStyle,
- "lines.solid_capstyle": CapStyle,
- "lines.dashed_pattern": validate_floatlist,
- "lines.dashdot_pattern": validate_floatlist,
- "lines.dotted_pattern": validate_floatlist,
- "lines.scale_dashes": validate_bool,
- # marker props
- "markers.fillstyle": validate_fillstyle,
- ## pcolor(mesh) props:
- "pcolor.shading": ["auto", "flat", "nearest", "gouraud"],
- "pcolormesh.snap": validate_bool,
- ## patch props
- "patch.linewidth": validate_float, # line width in points
- "patch.edgecolor": validate_color,
- "patch.force_edgecolor": validate_bool,
- "patch.facecolor": validate_color, # first color in cycle
- "patch.antialiased": validate_bool, # antialiased (no jaggies)
- ## hatch props
- "hatch.color": validate_color,
- "hatch.linewidth": validate_float,
- ## Histogram properties
- "hist.bins": validate_hist_bins,
- ## Boxplot properties
- "boxplot.notch": validate_bool,
- "boxplot.vertical": validate_bool,
- "boxplot.whiskers": validate_whiskers,
- "boxplot.bootstrap": validate_int_or_None,
- "boxplot.patchartist": validate_bool,
- "boxplot.showmeans": validate_bool,
- "boxplot.showcaps": validate_bool,
- "boxplot.showbox": validate_bool,
- "boxplot.showfliers": validate_bool,
- "boxplot.meanline": validate_bool,
- "boxplot.flierprops.color": validate_color,
- "boxplot.flierprops.marker": validate_string,
- "boxplot.flierprops.markerfacecolor": validate_color_or_auto,
- "boxplot.flierprops.markeredgecolor": validate_color,
- "boxplot.flierprops.markeredgewidth": validate_float,
- "boxplot.flierprops.markersize": validate_float,
- "boxplot.flierprops.linestyle": _validate_linestyle,
- "boxplot.flierprops.linewidth": validate_float,
- "boxplot.boxprops.color": validate_color,
- "boxplot.boxprops.linewidth": validate_float,
- "boxplot.boxprops.linestyle": _validate_linestyle,
- "boxplot.whiskerprops.color": validate_color,
- "boxplot.whiskerprops.linewidth": validate_float,
- "boxplot.whiskerprops.linestyle": _validate_linestyle,
- "boxplot.capprops.color": validate_color,
- "boxplot.capprops.linewidth": validate_float,
- "boxplot.capprops.linestyle": _validate_linestyle,
- "boxplot.medianprops.color": validate_color,
- "boxplot.medianprops.linewidth": validate_float,
- "boxplot.medianprops.linestyle": _validate_linestyle,
- "boxplot.meanprops.color": validate_color,
- "boxplot.meanprops.marker": validate_string,
- "boxplot.meanprops.markerfacecolor": validate_color,
- "boxplot.meanprops.markeredgecolor": validate_color,
- "boxplot.meanprops.markersize": validate_float,
- "boxplot.meanprops.linestyle": _validate_linestyle,
- "boxplot.meanprops.linewidth": validate_float,
- ## font props
- "font.family": validate_stringlist, # used by text object
- "font.style": validate_string,
- "font.variant": validate_string,
- "font.stretch": validate_fontstretch,
- "font.weight": validate_fontweight,
- "font.size": validate_float, # Base font size in points
- "font.serif": validate_stringlist,
- "font.sans-serif": validate_stringlist,
- "font.cursive": validate_stringlist,
- "font.fantasy": validate_stringlist,
- "font.monospace": validate_stringlist,
- # text props
- "text.color": validate_color,
- "text.usetex": validate_bool,
- "text.latex.preamble": validate_string,
- "text.hinting": ["default", "no_autohint", "force_autohint",
- "no_hinting", "auto", "native", "either", "none"],
- "text.hinting_factor": validate_int,
- "text.kerning_factor": validate_int,
- "text.antialiased": validate_bool,
- "text.parse_math": validate_bool,
- "mathtext.cal": validate_font_properties,
- "mathtext.rm": validate_font_properties,
- "mathtext.tt": validate_font_properties,
- "mathtext.it": validate_font_properties,
- "mathtext.bf": validate_font_properties,
- "mathtext.bfit": validate_font_properties,
- "mathtext.sf": validate_font_properties,
- "mathtext.fontset": ["dejavusans", "dejavuserif", "cm", "stix",
- "stixsans", "custom"],
- "mathtext.default": ["rm", "cal", "bfit", "it", "tt", "sf", "bf", "default",
- "bb", "frak", "scr", "regular"],
- "mathtext.fallback": _validate_mathtext_fallback,
- "image.aspect": validate_aspect, # equal, auto, a number
- "image.interpolation": validate_string,
- "image.cmap": _validate_cmap, # gray, jet, etc.
- "image.lut": validate_int, # lookup table
- "image.origin": ["upper", "lower"],
- "image.resample": validate_bool,
- # Specify whether vector graphics backends will combine all images on a
- # set of axes into a single composite image
- "image.composite_image": validate_bool,
- # contour props
- "contour.negative_linestyle": _validate_linestyle,
- "contour.corner_mask": validate_bool,
- "contour.linewidth": validate_float_or_None,
- "contour.algorithm": ["mpl2005", "mpl2014", "serial", "threaded"],
- # errorbar props
- "errorbar.capsize": validate_float,
- # axis props
- # alignment of x/y axis title
- "xaxis.labellocation": ["left", "center", "right"],
- "yaxis.labellocation": ["bottom", "center", "top"],
- # axes props
- "axes.axisbelow": validate_axisbelow,
- "axes.facecolor": validate_color, # background color
- "axes.edgecolor": validate_color, # edge color
- "axes.linewidth": validate_float, # edge linewidth
- "axes.spines.left": validate_bool, # Set visibility of axes spines,
- "axes.spines.right": validate_bool, # i.e., the lines around the chart
- "axes.spines.bottom": validate_bool, # denoting data boundary.
- "axes.spines.top": validate_bool,
- "axes.titlesize": validate_fontsize, # axes title fontsize
- "axes.titlelocation": ["left", "center", "right"], # axes title alignment
- "axes.titleweight": validate_fontweight, # axes title font weight
- "axes.titlecolor": validate_color_or_auto, # axes title font color
- # title location, axes units, None means auto
- "axes.titley": validate_float_or_None,
- # pad from axes top decoration to title in points
- "axes.titlepad": validate_float,
- "axes.grid": validate_bool, # display grid or not
- "axes.grid.which": ["minor", "both", "major"], # which grids are drawn
- "axes.grid.axis": ["x", "y", "both"], # grid type
- "axes.labelsize": validate_fontsize, # fontsize of x & y labels
- "axes.labelpad": validate_float, # space between label and axis
- "axes.labelweight": validate_fontweight, # fontsize of x & y labels
- "axes.labelcolor": validate_color, # color of axis label
- # use scientific notation if log10 of the axis range is smaller than the
- # first or larger than the second
- "axes.formatter.limits": _listify_validator(validate_int, n=2),
- # use current locale to format ticks
- "axes.formatter.use_locale": validate_bool,
- "axes.formatter.use_mathtext": validate_bool,
- # minimum exponent to format in scientific notation
- "axes.formatter.min_exponent": validate_int,
- "axes.formatter.useoffset": validate_bool,
- "axes.formatter.offset_threshold": validate_int,
- "axes.unicode_minus": validate_bool,
- # This entry can be either a cycler object or a string repr of a
- # cycler-object, which gets eval()'ed to create the object.
- "axes.prop_cycle": validate_cycler,
- # If "data", axes limits are set close to the data.
- # If "round_numbers" axes limits are set to the nearest round numbers.
- "axes.autolimit_mode": ["data", "round_numbers"],
- "axes.xmargin": _validate_greaterthan_minushalf, # margin added to xaxis
- "axes.ymargin": _validate_greaterthan_minushalf, # margin added to yaxis
- "axes.zmargin": _validate_greaterthan_minushalf, # margin added to zaxis
- "polaraxes.grid": validate_bool, # display polar grid or not
- "axes3d.grid": validate_bool, # display 3d grid
- "axes3d.xaxis.panecolor": validate_color, # 3d background pane
- "axes3d.yaxis.panecolor": validate_color, # 3d background pane
- "axes3d.zaxis.panecolor": validate_color, # 3d background pane
- # scatter props
- "scatter.marker": validate_string,
- "scatter.edgecolors": validate_string,
- "date.epoch": _validate_date,
- "date.autoformatter.year": validate_string,
- "date.autoformatter.month": validate_string,
- "date.autoformatter.day": validate_string,
- "date.autoformatter.hour": validate_string,
- "date.autoformatter.minute": validate_string,
- "date.autoformatter.second": validate_string,
- "date.autoformatter.microsecond": validate_string,
- 'date.converter': ['auto', 'concise'],
- # for auto date locator, choose interval_multiples
- 'date.interval_multiples': validate_bool,
- # legend properties
- "legend.fancybox": validate_bool,
- "legend.loc": _validate_legend_loc,
- # the number of points in the legend line
- "legend.numpoints": validate_int,
- # the number of points in the legend line for scatter
- "legend.scatterpoints": validate_int,
- "legend.fontsize": validate_fontsize,
- "legend.title_fontsize": validate_fontsize_None,
- # color of the legend
- "legend.labelcolor": _validate_color_or_linecolor,
- # the relative size of legend markers vs. original
- "legend.markerscale": validate_float,
- # using dict in rcParams not yet supported, so make sure it is bool
- "legend.shadow": validate_bool,
- # whether or not to draw a frame around legend
- "legend.frameon": validate_bool,
- # alpha value of the legend frame
- "legend.framealpha": validate_float_or_None,
- ## the following dimensions are in fraction of the font size
- "legend.borderpad": validate_float, # units are fontsize
- # the vertical space between the legend entries
- "legend.labelspacing": validate_float,
- # the length of the legend lines
- "legend.handlelength": validate_float,
- # the length of the legend lines
- "legend.handleheight": validate_float,
- # the space between the legend line and legend text
- "legend.handletextpad": validate_float,
- # the border between the axes and legend edge
- "legend.borderaxespad": validate_float,
- # the border between the axes and legend edge
- "legend.columnspacing": validate_float,
- "legend.facecolor": validate_color_or_inherit,
- "legend.edgecolor": validate_color_or_inherit,
- # tick properties
- "xtick.top": validate_bool, # draw ticks on top side
- "xtick.bottom": validate_bool, # draw ticks on bottom side
- "xtick.labeltop": validate_bool, # draw label on top
- "xtick.labelbottom": validate_bool, # draw label on bottom
- "xtick.major.size": validate_float, # major xtick size in points
- "xtick.minor.size": validate_float, # minor xtick size in points
- "xtick.major.width": validate_float, # major xtick width in points
- "xtick.minor.width": validate_float, # minor xtick width in points
- "xtick.major.pad": validate_float, # distance to label in points
- "xtick.minor.pad": validate_float, # distance to label in points
- "xtick.color": validate_color, # color of xticks
- "xtick.labelcolor": validate_color_or_inherit, # color of xtick labels
- "xtick.minor.visible": validate_bool, # visibility of minor xticks
- "xtick.minor.top": validate_bool, # draw top minor xticks
- "xtick.minor.bottom": validate_bool, # draw bottom minor xticks
- "xtick.major.top": validate_bool, # draw top major xticks
- "xtick.major.bottom": validate_bool, # draw bottom major xticks
- # number of minor xticks
- "xtick.minor.ndivs": _validate_minor_tick_ndivs,
- "xtick.labelsize": validate_fontsize, # fontsize of xtick labels
- "xtick.direction": ["out", "in", "inout"], # direction of xticks
- "xtick.alignment": ["center", "right", "left"],
- "ytick.left": validate_bool, # draw ticks on left side
- "ytick.right": validate_bool, # draw ticks on right side
- "ytick.labelleft": validate_bool, # draw tick labels on left side
- "ytick.labelright": validate_bool, # draw tick labels on right side
- "ytick.major.size": validate_float, # major ytick size in points
- "ytick.minor.size": validate_float, # minor ytick size in points
- "ytick.major.width": validate_float, # major ytick width in points
- "ytick.minor.width": validate_float, # minor ytick width in points
- "ytick.major.pad": validate_float, # distance to label in points
- "ytick.minor.pad": validate_float, # distance to label in points
- "ytick.color": validate_color, # color of yticks
- "ytick.labelcolor": validate_color_or_inherit, # color of ytick labels
- "ytick.minor.visible": validate_bool, # visibility of minor yticks
- "ytick.minor.left": validate_bool, # draw left minor yticks
- "ytick.minor.right": validate_bool, # draw right minor yticks
- "ytick.major.left": validate_bool, # draw left major yticks
- "ytick.major.right": validate_bool, # draw right major yticks
- # number of minor yticks
- "ytick.minor.ndivs": _validate_minor_tick_ndivs,
- "ytick.labelsize": validate_fontsize, # fontsize of ytick labels
- "ytick.direction": ["out", "in", "inout"], # direction of yticks
- "ytick.alignment": [
- "center", "top", "bottom", "baseline", "center_baseline"],
- "grid.color": validate_color, # grid color
- "grid.linestyle": _validate_linestyle, # solid
- "grid.linewidth": validate_float, # in points
- "grid.alpha": validate_float,
- ## figure props
- # figure title
- "figure.titlesize": validate_fontsize,
- "figure.titleweight": validate_fontweight,
- # figure labels
- "figure.labelsize": validate_fontsize,
- "figure.labelweight": validate_fontweight,
- # figure size in inches: width by height
- "figure.figsize": _listify_validator(validate_float, n=2),
- "figure.dpi": validate_float,
- "figure.facecolor": validate_color,
- "figure.edgecolor": validate_color,
- "figure.frameon": validate_bool,
- "figure.autolayout": validate_bool,
- "figure.max_open_warning": validate_int,
- "figure.raise_window": validate_bool,
- "macosx.window_mode": ["system", "tab", "window"],
- "figure.subplot.left": validate_float,
- "figure.subplot.right": validate_float,
- "figure.subplot.bottom": validate_float,
- "figure.subplot.top": validate_float,
- "figure.subplot.wspace": validate_float,
- "figure.subplot.hspace": validate_float,
- "figure.constrained_layout.use": validate_bool, # run constrained_layout?
- # wspace and hspace are fraction of adjacent subplots to use for space.
- # Much smaller than above because we don't need room for the text.
- "figure.constrained_layout.hspace": validate_float,
- "figure.constrained_layout.wspace": validate_float,
- # buffer around the axes, in inches.
- "figure.constrained_layout.h_pad": validate_float,
- "figure.constrained_layout.w_pad": validate_float,
- ## Saving figure's properties
- 'savefig.dpi': validate_dpi,
- 'savefig.facecolor': validate_color_or_auto,
- 'savefig.edgecolor': validate_color_or_auto,
- 'savefig.orientation': ['landscape', 'portrait'],
- "savefig.format": validate_string,
- "savefig.bbox": validate_bbox, # "tight", or "standard" (= None)
- "savefig.pad_inches": validate_float,
- # default directory in savefig dialog box
- "savefig.directory": _validate_pathlike,
- "savefig.transparent": validate_bool,
- "tk.window_focus": validate_bool, # Maintain shell focus for TkAgg
- # Set the papersize/type
- "ps.papersize": _validate_papersize,
- "ps.useafm": validate_bool,
- # use ghostscript or xpdf to distill ps output
- "ps.usedistiller": validate_ps_distiller,
- "ps.distiller.res": validate_int, # dpi
- "ps.fonttype": validate_fonttype, # 3 (Type3) or 42 (Truetype)
- "pdf.compression": validate_int, # 0-9 compression level; 0 to disable
- "pdf.inheritcolor": validate_bool, # skip color setting commands
- # use only the 14 PDF core fonts embedded in every PDF viewing application
- "pdf.use14corefonts": validate_bool,
- "pdf.fonttype": validate_fonttype, # 3 (Type3) or 42 (Truetype)
- "pgf.texsystem": ["xelatex", "lualatex", "pdflatex"], # latex variant used
- "pgf.rcfonts": validate_bool, # use mpl's rc settings for font config
- "pgf.preamble": validate_string, # custom LaTeX preamble
- # write raster image data into the svg file
- "svg.image_inline": validate_bool,
- "svg.fonttype": ["none", "path"], # save text as text ("none") or "paths"
- "svg.hashsalt": validate_string_or_None,
- # set this when you want to generate hardcopy docstring
- "docstring.hardcopy": validate_bool,
- "path.simplify": validate_bool,
- "path.simplify_threshold": _validate_greaterequal0_lessequal1,
- "path.snap": validate_bool,
- "path.sketch": validate_sketch,
- "path.effects": validate_anylist,
- "agg.path.chunksize": validate_int, # 0 to disable chunking
- # key-mappings (multi-character mappings should be a list/tuple)
- "keymap.fullscreen": validate_stringlist,
- "keymap.home": validate_stringlist,
- "keymap.back": validate_stringlist,
- "keymap.forward": validate_stringlist,
- "keymap.pan": validate_stringlist,
- "keymap.zoom": validate_stringlist,
- "keymap.save": validate_stringlist,
- "keymap.quit": validate_stringlist,
- "keymap.quit_all": validate_stringlist, # e.g.: "W", "cmd+W", "Q"
- "keymap.grid": validate_stringlist,
- "keymap.grid_minor": validate_stringlist,
- "keymap.yscale": validate_stringlist,
- "keymap.xscale": validate_stringlist,
- "keymap.help": validate_stringlist,
- "keymap.copy": validate_stringlist,
- # Animation settings
- "animation.html": ["html5", "jshtml", "none"],
- # Limit, in MB, of size of base64 encoded animation in HTML
- # (i.e. IPython notebook)
- "animation.embed_limit": validate_float,
- "animation.writer": validate_string,
- "animation.codec": validate_string,
- "animation.bitrate": validate_int,
- # Controls image format when frames are written to disk
- "animation.frame_format": ["png", "jpeg", "tiff", "raw", "rgba", "ppm",
- "sgi", "bmp", "pbm", "svg"],
- # Path to ffmpeg binary. If just binary name, subprocess uses $PATH.
- "animation.ffmpeg_path": _validate_pathlike,
- # Additional arguments for ffmpeg movie writer (using pipes)
- "animation.ffmpeg_args": validate_stringlist,
- # Path to convert binary. If just binary name, subprocess uses $PATH.
- "animation.convert_path": _validate_pathlike,
- # Additional arguments for convert movie writer (using pipes)
- "animation.convert_args": validate_stringlist,
- # Classic (pre 2.0) compatibility mode
- # This is used for things that are hard to make backward compatible
- # with a sane rcParam alone. This does *not* turn on classic mode
- # altogether. For that use `matplotlib.style.use("classic")`.
- "_internal.classic_mode": validate_bool
- }
- _hardcoded_defaults = { # Defaults not inferred from
- # lib/matplotlib/mpl-data/matplotlibrc...
- # ... because they are private:
- "_internal.classic_mode": False,
- # ... because they are deprecated:
- # No current deprecations.
- # backend is handled separately when constructing rcParamsDefault.
- }
- _validators = {k: _convert_validator_spec(k, conv)
- for k, conv in _validators.items()}
|