12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505 |
- """
- 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:`matplotlibrc.template` in Matplotlib's root source
- directory.
- """
- import ast
- from functools import lru_cache, reduce
- import logging
- from numbers import Number
- import operator
- import os
- import re
- import numpy as np
- from matplotlib import animation, cbook
- from matplotlib.cbook import ls_mapper
- from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
- from matplotlib.colors import is_color_like
- # Don't let the original cycler collide with our validating cycler
- from cycler import Cycler, cycler as ccycler
- _log = logging.getLogger(__name__)
- # The capitalized forms are needed for ipython at present; this may
- # change for later versions.
- interactive_bk = ['GTK3Agg', 'GTK3Cairo',
- 'MacOSX',
- 'nbAgg',
- 'Qt4Agg', 'Qt4Cairo', '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)
- cbook.warn_deprecated(
- self._deprecated_since, name=name, obj_type="function")
- if self.ignorecase:
- 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__ = "{}list".format(scalar_validator.__name__)
- except AttributeError: # class instance.
- f.__name__ = "{}List".format(type(scalar_validator).__name__)
- 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')
- @cbook.deprecated("3.2", alternative="os.path.exists")
- def validate_path_exists(s):
- """If s is a path, return s, else False"""
- if s is None:
- return None
- if os.path.exists(s):
- return s
- else:
- raise RuntimeError('"%s" should be a path but it does not exist' % s)
- 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('Could not convert "%s" to bool' % b)
- @cbook.deprecated("3.3")
- def validate_bool_maybe_none(b):
- """Convert b to ``bool`` or raise, passing through *None*."""
- if isinstance(b, str):
- b = b.lower()
- if b is None or b == 'none':
- return None
- 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('Could not convert "%s" to bool' % b)
- def _validate_tex_preamble(s):
- if s is None or s == 'None':
- cbook.warn_deprecated(
- "3.3", message="Support for setting the 'text.latex.preamble' or "
- "'pgf.preamble' rcParam to None is deprecated since %(since)s and "
- "will be removed %(removal)s; set it to an empty string instead.")
- return ""
- try:
- if isinstance(s, str):
- return s
- elif np.iterable(s):
- cbook.warn_deprecated(
- "3.3", message="Support for setting the 'text.latex.preamble' "
- "or 'pgf.preamble' rcParam to a list of strings is deprecated "
- "since %(since)s and will be removed %(removal)s; set it to a "
- "single string instead.")
- return '\n'.join(s)
- else:
- raise TypeError
- except TypeError as e:
- raise ValueError('Could not convert "%s" to string' % s) from e
- def validate_axisbelow(s):
- try:
- return validate_bool(s)
- except ValueError:
- if isinstance(s, str):
- if s == 'line':
- return 'line'
- if s.lower().startswith('line'):
- cbook.warn_deprecated(
- "3.3", message=f"Support for setting axes.axisbelow to "
- f"{s!r} to mean 'line' is deprecated since %(since)s and "
- f"will be removed %(removal)s; set it to 'line' instead.")
- return 'line'
- raise ValueError('%s cannot be interpreted as'
- ' True, False, or "line"' % s)
- 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
- try:
- return cls(s)
- except 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_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
- validate_toolbar = ValidateInStrings(
- 'toolbar', ['None', 'toolbar2', 'toolmanager'], ignorecase=True,
- _deprecated_since="3.3")
- @cbook.deprecated("3.3")
- def _make_nseq_validator(cls, n=None, allow_none=False):
- def validator(s):
- """Convert *n* objects using ``cls``, or raise."""
- if isinstance(s, str):
- s = [x.strip() for x in s.split(',')]
- if n is not None and len(s) != n:
- raise ValueError(
- f'Expected exactly {n} comma-separated values, '
- f'but got {len(s)} comma-separated values: {s}')
- else:
- if n is not None and len(s) != n:
- raise ValueError(
- f'Expected exactly {n} values, '
- f'but got {len(s)} values: {s}')
- try:
- return [cls(val) if not allow_none or val is not None else val
- for val in s]
- except ValueError as e:
- raise ValueError(
- f'Could not convert all entries to {cls.__name__}s') from e
- return validator
- @cbook.deprecated("3.3")
- def validate_nseq_float(n):
- return _make_nseq_validator(float, n)
- @cbook.deprecated("3.3")
- def validate_nseq_int(n):
- return _make_nseq_validator(int, n)
- 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(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')
- validate_orientation = ValidateInStrings(
- 'orientation', ['landscape', 'portrait'], _deprecated_since="3.3")
- 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_font_properties(s):
- parse_fontconfig_pattern(s)
- return s
- def _validate_mathtext_fallback_to_cm(b):
- """
- Temporary validate for fallback_to_cm, while deprecated
- """
- if isinstance(b, str):
- b = b.lower()
- if b is None or b == 'none':
- return None
- else:
- cbook.warn_deprecated(
- "3.3", message="Support for setting the 'mathtext.fallback_to_cm' "
- "rcParam is deprecated since %(since)s and will be removed "
- "%(removal)s; use 'mathtext.fallback : 'cm' instead.")
- return validate_bool_maybe_none(b)
- 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.")
- validate_fontset = ValidateInStrings(
- 'fontset',
- ['dejavusans', 'dejavuserif', 'cm', 'stix', 'stixsans', 'custom'],
- _deprecated_since="3.3")
- validate_mathtext_default = ValidateInStrings(
- 'default', "rm cal it tt sf bf default bb frak scr regular".split(),
- _deprecated_since="3.3")
- _validate_alignment = ValidateInStrings(
- 'alignment',
- ['center', 'top', 'bottom', 'baseline', 'center_baseline'],
- _deprecated_since="3.3")
- def validate_whiskers(s):
- if s == 'range':
- cbook.warn_deprecated(
- "3.2", message="Support for setting the boxplot.whiskers rcParam "
- "to 'range' is deprecated since %(since)s and will be removed "
- "%(removal)s; set it to 0, 100 instead.")
- return 'range'
- else:
- 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 ['range', float, "
- "(float, float)]") from e
- @cbook.deprecated("3.2")
- def update_savefig_format(value):
- # The old savefig.extension could also have a value of "auto", but
- # the new savefig.format does not. We need to fix this here.
- value = validate_string(value)
- if value == 'auto':
- cbook.warn_deprecated(
- "3.2", message="Support for setting the 'savefig.format' rcParam "
- "to 'auto' is deprecated since %(since)s and will be removed "
- "%(removal)s; set it to 'png' instead.")
- value = 'png'
- return value
- # Replace by validate_string once deprecation period passes.
- def _update_savefig_format(value):
- # The old savefig.extension could also have a value of "auto", but
- # the new savefig.format does not. We need to fix this here.
- value = validate_string(value)
- if value == 'auto':
- cbook.warn_deprecated(
- "3.2", message="Support for setting the 'savefig.format' rcParam "
- "to 'auto' is deprecated since %(since)s and will be removed "
- "%(removal)s; set it to 'png' instead.")
- value = 'png'
- return value
- validate_ps_papersize = ValidateInStrings(
- 'ps_papersize',
- ['auto', 'letter', 'legal', 'ledger',
- 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10',
- 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b10',
- ], ignorecase=True, _deprecated_since="3.3")
- 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)
- # 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))
- # (offset, (on, off, on, off, ...))
- if (_is_iterable_not_string_like(ls)
- and len(ls) == 2
- and isinstance(ls[0], (type(None), Number))
- and _is_iterable_not_string_like(ls[1])
- and len(ls[1]) % 2 == 0
- and all(isinstance(elem, Number) for elem in ls[1])):
- if ls[0] is None:
- cbook.warn_deprecated(
- "3.3", message="Passing the dash offset as None is deprecated "
- "since %(since)s and support for it will be removed "
- "%(removal)s; pass it as zero instead.")
- ls = (0, ls[1])
- return ls
- # For backcompat: (on, off, on, off, ...); the offset is implicitly None.
- if (_is_iterable_not_string_like(ls)
- and len(ls) % 2 == 0
- and all(isinstance(elem, Number) for elem in ls)):
- return (0, ls)
- raise ValueError(f"linestyle {ls!r} is not a valid on-off ink sequence.")
- def _deprecate_case_insensitive_join_cap(s):
- s_low = s.lower()
- if s != s_low:
- if s_low in ['miter', 'round', 'bevel']:
- cbook.warn_deprecated(
- "3.3", message="Case-insensitive capstyles are deprecated "
- "since %(since)s and support for them will be removed "
- "%(removal)s; please pass them in lowercase.")
- elif s_low in ['butt', 'round', 'projecting']:
- cbook.warn_deprecated(
- "3.3", message="Case-insensitive joinstyles are deprecated "
- "since %(since)s and support for them will be removed "
- "%(removal)s; please pass them in lowercase.")
- # Else, error out at the check_in_list stage.
- return s_low
- def validate_joinstyle(s):
- s = _deprecate_case_insensitive_join_cap(s)
- cbook._check_in_list(['miter', 'round', 'bevel'], joinstyle=s)
- return s
- def validate_capstyle(s):
- s = _deprecate_case_insensitive_join_cap(s)
- cbook._check_in_list(['butt', 'round', 'projecting'], capstyle=s)
- return s
- validate_fillstyle = ValidateInStrings(
- 'markers.fillstyle', ['full', 'left', 'right', 'bottom', 'top', 'none'])
- validate_joinstylelist = _listify_validator(validate_joinstyle)
- validate_capstylelist = _listify_validator(validate_capstyle)
- validate_fillstylelist = _listify_validator(validate_fillstyle)
- def validate_markevery(s):
- """
- Validate the markevery property of a Line2D object.
- Parameters
- ----------
- s : None, int, float, slice, length-2 tuple of ints,
- length-2 tuple of floats, list of ints
- Returns
- -------
- None, int, float, slice, length-2 tuple of ints,
- length-2 tuple of floats, list of ints
- """
- # 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)
- validate_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, _deprecated_since="3.3")
- validate_svg_fonttype = ValidateInStrings(
- 'svg.fonttype', ['none', 'path'], _deprecated_since="3.3")
- @cbook.deprecated("3.3")
- def validate_hinting(s):
- return _validate_hinting(s)
- # Replace by plain list in _prop_validators after deprecation period.
- def _validate_hinting(s):
- if s in (True, False):
- cbook.warn_deprecated(
- "3.2", message="Support for setting the text.hinting rcParam to "
- "True or False is deprecated since %(since)s and will be removed "
- "%(removal)s; set it to its synonyms 'auto' or 'none' instead.")
- return s
- return ValidateInStrings(
- 'text.hinting',
- ['default', 'no_autohint', 'force_autohint', 'no_hinting',
- 'auto', 'native', 'either', 'none'],
- ignorecase=True)(s)
- validate_pgf_texsystem = ValidateInStrings(
- 'pgf.texsystem', ['xelatex', 'lualatex', 'pdflatex'],
- _deprecated_since="3.3")
- @cbook.deprecated("3.3")
- def validate_movie_writer(s):
- # writers.list() would only list actually available writers, but
- # FFMpeg.isAvailable is slow and not worth paying for at every import.
- if s in animation.writers._registered:
- return s
- else:
- raise ValueError(f"Supported animation writers are "
- f"{sorted(animation.writers._registered)}")
- validate_movie_frame_fmt = ValidateInStrings(
- 'animation.frame_format', ['png', 'jpeg', 'tiff', 'raw', 'rgba'],
- _deprecated_since="3.3")
- validate_axis_locator = ValidateInStrings(
- 'major', ['minor', 'both', 'major'], _deprecated_since="3.3")
- validate_movie_html_fmt = ValidateInStrings(
- 'animation.html', ['html5', 'jshtml', 'none'], _deprecated_since="3.3")
- 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_greaterequal0_lessthan1(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_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}')
- _range_validators = { # Slightly nicer (internal) API.
- "0 <= x < 1": _validate_greaterequal0_lessthan1,
- "0 <= x <= 1": _validate_greaterequal0_lessequal1,
- }
- validate_grid_axis = ValidateInStrings(
- 'axes.grid.axis', ['x', 'y', 'both'], _deprecated_since="3.3")
- 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")
- cbook._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)
- _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': validate_joinstylelist,
- 'capstyle': validate_capstylelist,
- '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 TypeError("No more than 2 positional arguments allowed")
- 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))
- 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:
- # http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
- # We should replace this eval with a combo of PyParsing and
- # ast.literal_eval()
- try:
- if '.__' in s.replace(' ', ''):
- raise ValueError("'%s' seems to have dunder methods. Raising"
- " an exception for your safety")
- s = eval(s, {'cycler': cycler, '__builtins__': {}})
- except BaseException as e:
- raise ValueError("'%s' is not a valid cycler construction: %s" %
- (s, 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("object was not a string or Cycler instance: %s" % s)
- 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("Cannot specify both '{0}' and alias '{1}'"
- " in the same prop_cycle".format(norm_prop, prop))
- if norm_prop in checker:
- raise ValueError("Another property was already aliased to '{0}'."
- " Collision normalizing '{1}'.".format(norm_prop,
- prop))
- 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("'hist.bins' must be one of {}, an int or"
- " a sequence of floats".format(valid_strs))
- @cbook.deprecated("3.2")
- def validate_animation_writer_path(p):
- # Make sure it's a string and then figure out if the animations
- # are already loaded and reset the writers (which will validate
- # the path on next call)
- cbook._check_isinstance(str, path=p)
- from sys import modules
- # set dirty, so that the next call to the registry will re-evaluate
- # the state.
- # only set dirty if already loaded. If not loaded, the load will
- # trigger the checks.
- if "matplotlib.animation" in modules:
- modules["matplotlib.animation"].writers.set_dirty()
- return p
- @cbook.deprecated("3.3")
- def validate_webagg_address(s):
- if s is not None:
- import socket
- try:
- socket.inet_aton(s)
- except socket.error as e:
- raise ValueError(
- "'webagg.address' is not a valid IP address") from e
- return s
- raise ValueError("'webagg.address' is not a valid IP address")
- validate_axes_titlelocation = ValidateInStrings(
- 'axes.titlelocation', ['left', 'center', 'right'], _deprecated_since="3.3")
- 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 matplotlibrc.template, which gets copied
- # to matplotlib/mpl-data/matplotlibrc by the setup script.
- _validators = {
- "backend": validate_backend,
- "backend_fallback": validate_bool,
- "toolbar": _ignorecase(["none", "toolbar2", "toolmanager"]),
- "datapath": validate_any, # see _get_data_path_cached
- "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": validate_joinstyle,
- "lines.solid_joinstyle": validate_joinstyle,
- "lines.dash_capstyle": validate_capstyle,
- "lines.solid_capstyle": validate_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"],
- ## 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_string,
- "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_tex_preamble,
- "text.latex.preview": validate_bool,
- "text.hinting": _validate_hinting,
- "text.hinting_factor": validate_int,
- "text.kerning_factor": validate_int,
- "text.antialiased": 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.sf": validate_font_properties,
- "mathtext.fontset": ["dejavusans", "dejavuserif", "cm", "stix",
- "stixsans", "custom"],
- "mathtext.default": ["rm", "cal", "it", "tt", "sf", "bf", "default",
- "bb", "frak", "scr", "regular"],
- "mathtext.fallback_to_cm": _validate_mathtext_fallback_to_cm,
- "mathtext.fallback": _validate_mathtext_fallback,
- "image.aspect": validate_aspect, # equal, auto, a number
- "image.interpolation": validate_string,
- "image.cmap": validate_string, # 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,
- # 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": _range_validators["0 <= x <= 1"], # margin added to xaxis
- "axes.ymargin": _range_validators["0 <= x <= 1"], # margin added to yaxis
- "polaraxes.grid": validate_bool, # display polar grid or not
- "axes3d.grid": validate_bool, # display 3d grid
- # 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,
- # legend properties
- "legend.fancybox": validate_bool,
- "legend.loc": _ignorecase([
- "best",
- "upper right", "upper left", "lower left", "lower right", "right",
- "center left", "center right", "lower center", "upper center",
- "center"]),
- # 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,
- # the relative size of legend markers vs. original
- "legend.markerscale": validate_float,
- "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 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
- "xtick.labelsize": validate_fontsize, # fontsize of xtick labels
- "xtick.direction": validate_string, # 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 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
- "ytick.labelsize": validate_fontsize, # fontsize of ytick labels
- "ytick.direction": validate_string, # 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 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,
- "figure.subplot.left": _range_validators["0 <= x <= 1"],
- "figure.subplot.right": _range_validators["0 <= x <= 1"],
- "figure.subplot.bottom": _range_validators["0 <= x <= 1"],
- "figure.subplot.top": _range_validators["0 <= x <= 1"],
- "figure.subplot.wspace": _range_validators["0 <= x < 1"],
- "figure.subplot.hspace": _range_validators["0 <= x < 1"],
- "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": _range_validators["0 <= x < 1"],
- "figure.constrained_layout.wspace": _range_validators["0 <= x < 1"],
- # 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.jpeg_quality': validate_int,
- "savefig.format": _update_savefig_format,
- "savefig.bbox": validate_bbox, # "tight", or "standard" (= None)
- "savefig.pad_inches": validate_float,
- # default directory in savefig dialog box
- "savefig.directory": validate_string,
- "savefig.transparent": validate_bool,
- "tk.window_focus": validate_bool, # Maintain shell focus for TkAgg
- # Set the papersize/type
- "ps.papersize": _ignorecase(["auto", "letter", "legal", "ledger",
- *[f"{ab}{i}"
- for ab in "ab" for i in range(11)]]),
- "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_tex_preamble, # 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": _range_validators["0 <= x <= 1"],
- "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.all_axes": 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"],
- # Additional arguments for HTML writer
- "animation.html_args": validate_stringlist,
- # Path to ffmpeg binary. If just binary name, subprocess uses $PATH.
- "animation.ffmpeg_path": validate_string,
- # Additional arguments for ffmpeg movie writer (using pipes)
- "animation.ffmpeg_args": validate_stringlist,
- # Path to AVConv binary. If just binary name, subprocess uses $PATH.
- "animation.avconv_path": validate_string,
- # Additional arguments for avconv movie writer (using pipes)
- "animation.avconv_args": validate_stringlist,
- # Path to convert binary. If just binary name, subprocess uses $PATH.
- "animation.convert_path": validate_string,
- # Additional arguments for convert movie writer (using pipes)
- "animation.convert_args": validate_stringlist,
- "mpl_toolkits.legacy_colorbar": validate_bool,
- # 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 matplotlibrc.template...
- # ... because it can"t be:
- "backend": _auto_backend_sentinel,
- # ... because they are private:
- "_internal.classic_mode": False,
- # ... because they are deprecated:
- "animation.avconv_path": "avconv",
- "animation.avconv_args": [],
- "animation.html_args": [],
- "mathtext.fallback_to_cm": None,
- "keymap.all_axes": ["a"],
- "savefig.jpeg_quality": 95,
- "text.latex.preview": False,
- }
- _validators = {k: _convert_validator_spec(k, conv)
- for k, conv in _validators.items()}
|