ZhengyangZhang commited on
Commit
7aa7deb
·
verified ·
1 Parent(s): 63f8f42

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. lib/python3.12/site-packages/matplotlib/_api/__init__.py +391 -0
  2. lib/python3.12/site-packages/matplotlib/_api/__init__.pyi +59 -0
  3. lib/python3.12/site-packages/matplotlib/sphinxext/__init__.py +0 -0
  4. lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/__init__.cpython-312.pyc +0 -0
  5. lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/figmpl_directive.cpython-312.pyc +0 -0
  6. lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/mathmpl.cpython-312.pyc +0 -0
  7. lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/plot_directive.cpython-312.pyc +0 -0
  8. lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/roles.cpython-312.pyc +0 -0
  9. lib/python3.12/site-packages/matplotlib/sphinxext/figmpl_directive.py +286 -0
  10. lib/python3.12/site-packages/matplotlib/sphinxext/mathmpl.py +242 -0
  11. lib/python3.12/site-packages/matplotlib/sphinxext/plot_directive.py +936 -0
  12. lib/python3.12/site-packages/matplotlib/sphinxext/roles.py +147 -0
  13. lib/python3.12/site-packages/matplotlib/tests/__pycache__/__init__.cpython-312.pyc +0 -0
  14. lib/python3.12/site-packages/matplotlib/tests/__pycache__/conftest.cpython-312.pyc +0 -0
  15. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_afm.cpython-312.pyc +0 -0
  16. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_agg.cpython-312.pyc +0 -0
  17. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_agg_filter.cpython-312.pyc +0 -0
  18. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_animation.cpython-312.pyc +0 -0
  19. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_api.cpython-312.pyc +0 -0
  20. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_arrow_patches.cpython-312.pyc +0 -0
  21. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_artist.cpython-312.pyc +0 -0
  22. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_axis.cpython-312.pyc +0 -0
  23. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_bases.cpython-312.pyc +0 -0
  24. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_cairo.cpython-312.pyc +0 -0
  25. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_gtk3.cpython-312.pyc +0 -0
  26. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_inline.cpython-312.pyc +0 -0
  27. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_macosx.cpython-312.pyc +0 -0
  28. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_nbagg.cpython-312.pyc +0 -0
  29. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_pdf.cpython-312.pyc +0 -0
  30. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_pgf.cpython-312.pyc +0 -0
  31. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_ps.cpython-312.pyc +0 -0
  32. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_qt.cpython-312.pyc +0 -0
  33. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_registry.cpython-312.pyc +0 -0
  34. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_svg.cpython-312.pyc +0 -0
  35. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_template.cpython-312.pyc +0 -0
  36. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_tk.cpython-312.pyc +0 -0
  37. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_tools.cpython-312.pyc +0 -0
  38. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_webagg.cpython-312.pyc +0 -0
  39. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backends_interactive.cpython-312.pyc +0 -0
  40. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_basic.cpython-312.pyc +0 -0
  41. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_bbox_tight.cpython-312.pyc +0 -0
  42. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_bezier.cpython-312.pyc +0 -0
  43. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_category.cpython-312.pyc +0 -0
  44. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_cbook.cpython-312.pyc +0 -0
  45. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_collections.cpython-312.pyc +0 -0
  46. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_colorbar.cpython-312.pyc +0 -0
  47. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_colors.cpython-312.pyc +0 -0
  48. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_compare_images.cpython-312.pyc +0 -0
  49. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_constrainedlayout.cpython-312.pyc +0 -0
  50. lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_container.cpython-312.pyc +0 -0
lib/python3.12/site-packages/matplotlib/_api/__init__.py ADDED
@@ -0,0 +1,391 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Helper functions for managing the Matplotlib API.
3
+
4
+ This documentation is only relevant for Matplotlib developers, not for users.
5
+
6
+ .. warning::
7
+
8
+ This module and its submodules are for internal use only. Do not use them
9
+ in your own code. We may change the API at any time with no warning.
10
+
11
+ """
12
+
13
+ import functools
14
+ import itertools
15
+ import pathlib
16
+ import re
17
+ import sys
18
+ import warnings
19
+
20
+ from .deprecation import ( # noqa: F401
21
+ deprecated, warn_deprecated,
22
+ rename_parameter, delete_parameter, make_keyword_only,
23
+ deprecate_method_override, deprecate_privatize_attribute,
24
+ suppress_matplotlib_deprecation_warning,
25
+ MatplotlibDeprecationWarning)
26
+
27
+
28
+ class classproperty:
29
+ """
30
+ Like `property`, but also triggers on access via the class, and it is the
31
+ *class* that's passed as argument.
32
+
33
+ Examples
34
+ --------
35
+ ::
36
+
37
+ class C:
38
+ @classproperty
39
+ def foo(cls):
40
+ return cls.__name__
41
+
42
+ assert C.foo == "C"
43
+ """
44
+
45
+ def __init__(self, fget, fset=None, fdel=None, doc=None):
46
+ self._fget = fget
47
+ if fset is not None or fdel is not None:
48
+ raise ValueError('classproperty only implements fget.')
49
+ self.fset = fset
50
+ self.fdel = fdel
51
+ # docs are ignored for now
52
+ self._doc = doc
53
+
54
+ def __get__(self, instance, owner):
55
+ return self._fget(owner)
56
+
57
+ @property
58
+ def fget(self):
59
+ return self._fget
60
+
61
+
62
+ # In the following check_foo() functions, the first parameter is positional-only to make
63
+ # e.g. `_api.check_isinstance([...], types=foo)` work.
64
+
65
+ def check_isinstance(types, /, **kwargs):
66
+ """
67
+ For each *key, value* pair in *kwargs*, check that *value* is an instance
68
+ of one of *types*; if not, raise an appropriate TypeError.
69
+
70
+ As a special case, a ``None`` entry in *types* is treated as NoneType.
71
+
72
+ Examples
73
+ --------
74
+ >>> _api.check_isinstance((SomeClass, None), arg=arg)
75
+ """
76
+ none_type = type(None)
77
+ types = ((types,) if isinstance(types, type) else
78
+ (none_type,) if types is None else
79
+ tuple(none_type if tp is None else tp for tp in types))
80
+
81
+ def type_name(tp):
82
+ return ("None" if tp is none_type
83
+ else tp.__qualname__ if tp.__module__ == "builtins"
84
+ else f"{tp.__module__}.{tp.__qualname__}")
85
+
86
+ for k, v in kwargs.items():
87
+ if not isinstance(v, types):
88
+ names = [*map(type_name, types)]
89
+ if "None" in names: # Move it to the end for better wording.
90
+ names.remove("None")
91
+ names.append("None")
92
+ raise TypeError(
93
+ "{!r} must be an instance of {}, not a {}".format(
94
+ k,
95
+ ", ".join(names[:-1]) + " or " + names[-1]
96
+ if len(names) > 1 else names[0],
97
+ type_name(type(v))))
98
+
99
+
100
+ def check_in_list(values, /, *, _print_supported_values=True, **kwargs):
101
+ """
102
+ For each *key, value* pair in *kwargs*, check that *value* is in *values*;
103
+ if not, raise an appropriate ValueError.
104
+
105
+ Parameters
106
+ ----------
107
+ values : iterable
108
+ Sequence of values to check on.
109
+ _print_supported_values : bool, default: True
110
+ Whether to print *values* when raising ValueError.
111
+ **kwargs : dict
112
+ *key, value* pairs as keyword arguments to find in *values*.
113
+
114
+ Raises
115
+ ------
116
+ ValueError
117
+ If any *value* in *kwargs* is not found in *values*.
118
+
119
+ Examples
120
+ --------
121
+ >>> _api.check_in_list(["foo", "bar"], arg=arg, other_arg=other_arg)
122
+ """
123
+ if not kwargs:
124
+ raise TypeError("No argument to check!")
125
+ for key, val in kwargs.items():
126
+ if val not in values:
127
+ msg = f"{val!r} is not a valid value for {key}"
128
+ if _print_supported_values:
129
+ msg += f"; supported values are {', '.join(map(repr, values))}"
130
+ raise ValueError(msg)
131
+
132
+
133
+ def check_shape(shape, /, **kwargs):
134
+ """
135
+ For each *key, value* pair in *kwargs*, check that *value* has the shape *shape*;
136
+ if not, raise an appropriate ValueError.
137
+
138
+ *None* in the shape is treated as a "free" size that can have any length.
139
+ e.g. (None, 2) -> (N, 2)
140
+
141
+ The values checked must be numpy arrays.
142
+
143
+ Examples
144
+ --------
145
+ To check for (N, 2) shaped arrays
146
+
147
+ >>> _api.check_shape((None, 2), arg=arg, other_arg=other_arg)
148
+ """
149
+ for k, v in kwargs.items():
150
+ data_shape = v.shape
151
+
152
+ if (len(data_shape) != len(shape)
153
+ or any(s != t and t is not None for s, t in zip(data_shape, shape))):
154
+ dim_labels = iter(itertools.chain(
155
+ 'NMLKJIH',
156
+ (f"D{i}" for i in itertools.count())))
157
+ text_shape = ", ".join([str(n) if n is not None else next(dim_labels)
158
+ for n in shape[::-1]][::-1])
159
+ if len(shape) == 1:
160
+ text_shape += ","
161
+
162
+ raise ValueError(
163
+ f"{k!r} must be {len(shape)}D with shape ({text_shape}), "
164
+ f"but your input has shape {v.shape}"
165
+ )
166
+
167
+
168
+ def check_getitem(mapping, /, **kwargs):
169
+ """
170
+ *kwargs* must consist of a single *key, value* pair. If *key* is in
171
+ *mapping*, return ``mapping[value]``; else, raise an appropriate
172
+ ValueError.
173
+
174
+ Examples
175
+ --------
176
+ >>> _api.check_getitem({"foo": "bar"}, arg=arg)
177
+ """
178
+ if len(kwargs) != 1:
179
+ raise ValueError("check_getitem takes a single keyword argument")
180
+ (k, v), = kwargs.items()
181
+ try:
182
+ return mapping[v]
183
+ except KeyError:
184
+ raise ValueError(
185
+ f"{v!r} is not a valid value for {k}; supported values are "
186
+ f"{', '.join(map(repr, mapping))}") from None
187
+
188
+
189
+ def caching_module_getattr(cls):
190
+ """
191
+ Helper decorator for implementing module-level ``__getattr__`` as a class.
192
+
193
+ This decorator must be used at the module toplevel as follows::
194
+
195
+ @caching_module_getattr
196
+ class __getattr__: # The class *must* be named ``__getattr__``.
197
+ @property # Only properties are taken into account.
198
+ def name(self): ...
199
+
200
+ The ``__getattr__`` class will be replaced by a ``__getattr__``
201
+ function such that trying to access ``name`` on the module will
202
+ resolve the corresponding property (which may be decorated e.g. with
203
+ ``_api.deprecated`` for deprecating module globals). The properties are
204
+ all implicitly cached. Moreover, a suitable AttributeError is generated
205
+ and raised if no property with the given name exists.
206
+ """
207
+
208
+ assert cls.__name__ == "__getattr__"
209
+ # Don't accidentally export cls dunders.
210
+ props = {name: prop for name, prop in vars(cls).items()
211
+ if isinstance(prop, property)}
212
+ instance = cls()
213
+
214
+ @functools.cache
215
+ def __getattr__(name):
216
+ if name in props:
217
+ return props[name].__get__(instance)
218
+ raise AttributeError(
219
+ f"module {cls.__module__!r} has no attribute {name!r}")
220
+
221
+ return __getattr__
222
+
223
+
224
+ def define_aliases(alias_d, cls=None):
225
+ """
226
+ Class decorator for defining property aliases.
227
+
228
+ Use as ::
229
+
230
+ @_api.define_aliases({"property": ["alias", ...], ...})
231
+ class C: ...
232
+
233
+ For each property, if the corresponding ``get_property`` is defined in the
234
+ class so far, an alias named ``get_alias`` will be defined; the same will
235
+ be done for setters. If neither the getter nor the setter exists, an
236
+ exception will be raised.
237
+
238
+ The alias map is stored as the ``_alias_map`` attribute on the class and
239
+ can be used by `.normalize_kwargs` (which assumes that higher priority
240
+ aliases come last).
241
+ """
242
+ if cls is None: # Return the actual class decorator.
243
+ return functools.partial(define_aliases, alias_d)
244
+
245
+ def make_alias(name): # Enforce a closure over *name*.
246
+ @functools.wraps(getattr(cls, name))
247
+ def method(self, *args, **kwargs):
248
+ return getattr(self, name)(*args, **kwargs)
249
+ return method
250
+
251
+ for prop, aliases in alias_d.items():
252
+ exists = False
253
+ for prefix in ["get_", "set_"]:
254
+ if prefix + prop in vars(cls):
255
+ exists = True
256
+ for alias in aliases:
257
+ method = make_alias(prefix + prop)
258
+ method.__name__ = prefix + alias
259
+ method.__doc__ = f"Alias for `{prefix + prop}`."
260
+ setattr(cls, prefix + alias, method)
261
+ if not exists:
262
+ raise ValueError(
263
+ f"Neither getter nor setter exists for {prop!r}")
264
+
265
+ def get_aliased_and_aliases(d):
266
+ return {*d, *(alias for aliases in d.values() for alias in aliases)}
267
+
268
+ preexisting_aliases = getattr(cls, "_alias_map", {})
269
+ conflicting = (get_aliased_and_aliases(preexisting_aliases)
270
+ & get_aliased_and_aliases(alias_d))
271
+ if conflicting:
272
+ # Need to decide on conflict resolution policy.
273
+ raise NotImplementedError(
274
+ f"Parent class already defines conflicting aliases: {conflicting}")
275
+ cls._alias_map = {**preexisting_aliases, **alias_d}
276
+ return cls
277
+
278
+
279
+ def select_matching_signature(funcs, *args, **kwargs):
280
+ """
281
+ Select and call the function that accepts ``*args, **kwargs``.
282
+
283
+ *funcs* is a list of functions which should not raise any exception (other
284
+ than `TypeError` if the arguments passed do not match their signature).
285
+
286
+ `select_matching_signature` tries to call each of the functions in *funcs*
287
+ with ``*args, **kwargs`` (in the order in which they are given). Calls
288
+ that fail with a `TypeError` are silently skipped. As soon as a call
289
+ succeeds, `select_matching_signature` returns its return value. If no
290
+ function accepts ``*args, **kwargs``, then the `TypeError` raised by the
291
+ last failing call is re-raised.
292
+
293
+ Callers should normally make sure that any ``*args, **kwargs`` can only
294
+ bind a single *func* (to avoid any ambiguity), although this is not checked
295
+ by `select_matching_signature`.
296
+
297
+ Notes
298
+ -----
299
+ `select_matching_signature` is intended to help implementing
300
+ signature-overloaded functions. In general, such functions should be
301
+ avoided, except for back-compatibility concerns. A typical use pattern is
302
+ ::
303
+
304
+ def my_func(*args, **kwargs):
305
+ params = select_matching_signature(
306
+ [lambda old1, old2: locals(), lambda new: locals()],
307
+ *args, **kwargs)
308
+ if "old1" in params:
309
+ warn_deprecated(...)
310
+ old1, old2 = params.values() # note that locals() is ordered.
311
+ else:
312
+ new, = params.values()
313
+ # do things with params
314
+
315
+ which allows *my_func* to be called either with two parameters (*old1* and
316
+ *old2*) or a single one (*new*). Note that the new signature is given
317
+ last, so that callers get a `TypeError` corresponding to the new signature
318
+ if the arguments they passed in do not match any signature.
319
+ """
320
+ # Rather than relying on locals() ordering, one could have just used func's
321
+ # signature (``bound = inspect.signature(func).bind(*args, **kwargs);
322
+ # bound.apply_defaults(); return bound``) but that is significantly slower.
323
+ for i, func in enumerate(funcs):
324
+ try:
325
+ return func(*args, **kwargs)
326
+ except TypeError:
327
+ if i == len(funcs) - 1:
328
+ raise
329
+
330
+
331
+ def nargs_error(name, takes, given):
332
+ """Generate a TypeError to be raised by function calls with wrong arity."""
333
+ return TypeError(f"{name}() takes {takes} positional arguments but "
334
+ f"{given} were given")
335
+
336
+
337
+ def kwarg_error(name, kw):
338
+ """
339
+ Generate a TypeError to be raised by function calls with wrong kwarg.
340
+
341
+ Parameters
342
+ ----------
343
+ name : str
344
+ The name of the calling function.
345
+ kw : str or Iterable[str]
346
+ Either the invalid keyword argument name, or an iterable yielding
347
+ invalid keyword arguments (e.g., a ``kwargs`` dict).
348
+ """
349
+ if not isinstance(kw, str):
350
+ kw = next(iter(kw))
351
+ return TypeError(f"{name}() got an unexpected keyword argument '{kw}'")
352
+
353
+
354
+ def recursive_subclasses(cls):
355
+ """Yield *cls* and direct and indirect subclasses of *cls*."""
356
+ yield cls
357
+ for subcls in cls.__subclasses__():
358
+ yield from recursive_subclasses(subcls)
359
+
360
+
361
+ def warn_external(message, category=None):
362
+ """
363
+ `warnings.warn` wrapper that sets *stacklevel* to "outside Matplotlib".
364
+
365
+ The original emitter of the warning can be obtained by patching this
366
+ function back to `warnings.warn`, i.e. ``_api.warn_external =
367
+ warnings.warn`` (or ``functools.partial(warnings.warn, stacklevel=2)``,
368
+ etc.).
369
+ """
370
+ kwargs = {}
371
+ if sys.version_info[:2] >= (3, 12):
372
+ # Go to Python's `site-packages` or `lib` from an editable install.
373
+ basedir = pathlib.Path(__file__).parents[2]
374
+ kwargs['skip_file_prefixes'] = (str(basedir / 'matplotlib'),
375
+ str(basedir / 'mpl_toolkits'))
376
+ else:
377
+ frame = sys._getframe()
378
+ for stacklevel in itertools.count(1):
379
+ if frame is None:
380
+ # when called in embedded context may hit frame is None
381
+ kwargs['stacklevel'] = stacklevel
382
+ break
383
+ if not re.match(r"\A(matplotlib|mpl_toolkits)(\Z|\.(?!tests\.))",
384
+ # Work around sphinx-gallery not setting __name__.
385
+ frame.f_globals.get("__name__", "")):
386
+ kwargs['stacklevel'] = stacklevel
387
+ break
388
+ frame = frame.f_back
389
+ # preemptively break reference cycle between locals and the frame
390
+ del frame
391
+ warnings.warn(message, category, **kwargs)
lib/python3.12/site-packages/matplotlib/_api/__init__.pyi ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections.abc import Callable, Generator, Iterable, Mapping, Sequence
2
+ from typing import Any, TypeVar, overload
3
+ from typing_extensions import Self # < Py 3.11
4
+
5
+ from numpy.typing import NDArray
6
+
7
+ from .deprecation import ( # noqa: F401, re-exported API
8
+ deprecated as deprecated,
9
+ warn_deprecated as warn_deprecated,
10
+ rename_parameter as rename_parameter,
11
+ delete_parameter as delete_parameter,
12
+ make_keyword_only as make_keyword_only,
13
+ deprecate_method_override as deprecate_method_override,
14
+ deprecate_privatize_attribute as deprecate_privatize_attribute,
15
+ suppress_matplotlib_deprecation_warning as suppress_matplotlib_deprecation_warning,
16
+ MatplotlibDeprecationWarning as MatplotlibDeprecationWarning,
17
+ )
18
+
19
+ _T = TypeVar("_T")
20
+
21
+ class classproperty(Any):
22
+ def __init__(
23
+ self,
24
+ fget: Callable[[_T], Any],
25
+ fset: None = ...,
26
+ fdel: None = ...,
27
+ doc: str | None = None,
28
+ ): ...
29
+ @overload
30
+ def __get__(self, instance: None, owner: None) -> Self: ...
31
+ @overload
32
+ def __get__(self, instance: object, owner: type[object]) -> Any: ...
33
+ @property
34
+ def fget(self) -> Callable[[_T], Any]: ...
35
+
36
+ def check_isinstance(
37
+ types: type | tuple[type | None, ...], /, **kwargs: Any
38
+ ) -> None: ...
39
+ def check_in_list(
40
+ values: Sequence[Any], /, *, _print_supported_values: bool = ..., **kwargs: Any
41
+ ) -> None: ...
42
+ def check_shape(shape: tuple[int | None, ...], /, **kwargs: NDArray) -> None: ...
43
+ def check_getitem(mapping: Mapping[Any, Any], /, **kwargs: Any) -> Any: ...
44
+ def caching_module_getattr(cls: type) -> Callable[[str], Any]: ...
45
+ @overload
46
+ def define_aliases(
47
+ alias_d: dict[str, list[str]], cls: None = ...
48
+ ) -> Callable[[type[_T]], type[_T]]: ...
49
+ @overload
50
+ def define_aliases(alias_d: dict[str, list[str]], cls: type[_T]) -> type[_T]: ...
51
+ def select_matching_signature(
52
+ funcs: list[Callable], *args: Any, **kwargs: Any
53
+ ) -> Any: ...
54
+ def nargs_error(name: str, takes: int | str, given: int) -> TypeError: ...
55
+ def kwarg_error(name: str, kw: str | Iterable[str]) -> TypeError: ...
56
+ def recursive_subclasses(cls: type) -> Generator[type, None, None]: ...
57
+ def warn_external(
58
+ message: str | Warning, category: type[Warning] | None = ...
59
+ ) -> None: ...
lib/python3.12/site-packages/matplotlib/sphinxext/__init__.py ADDED
File without changes
lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (199 Bytes). View file
 
lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/figmpl_directive.cpython-312.pyc ADDED
Binary file (11.2 kB). View file
 
lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/mathmpl.cpython-312.pyc ADDED
Binary file (11.1 kB). View file
 
lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/plot_directive.cpython-312.pyc ADDED
Binary file (37 kB). View file
 
lib/python3.12/site-packages/matplotlib/sphinxext/__pycache__/roles.cpython-312.pyc ADDED
Binary file (6.21 kB). View file
 
lib/python3.12/site-packages/matplotlib/sphinxext/figmpl_directive.py ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Add a ``figure-mpl`` directive that is a responsive version of ``figure``.
3
+
4
+ This implementation is very similar to ``.. figure::``, except it also allows a
5
+ ``srcset=`` argument to be passed to the image tag, hence allowing responsive
6
+ resolution images.
7
+
8
+ There is no particular reason this could not be used standalone, but is meant
9
+ to be used with :doc:`/api/sphinxext_plot_directive_api`.
10
+
11
+ Note that the directory organization is a bit different than ``.. figure::``.
12
+ See the *FigureMpl* documentation below.
13
+
14
+ """
15
+ import os
16
+ from os.path import relpath
17
+ from pathlib import PurePath, Path
18
+ import shutil
19
+
20
+ from docutils import nodes
21
+ from docutils.parsers.rst import directives
22
+ from docutils.parsers.rst.directives.images import Figure, Image
23
+ from sphinx.errors import ExtensionError
24
+
25
+ import matplotlib
26
+
27
+
28
+ class figmplnode(nodes.General, nodes.Element):
29
+ pass
30
+
31
+
32
+ class FigureMpl(Figure):
33
+ """
34
+ Implements a directive to allow an optional hidpi image.
35
+
36
+ Meant to be used with the *plot_srcset* configuration option in conf.py,
37
+ and gets set in the TEMPLATE of plot_directive.py
38
+
39
+ e.g.::
40
+
41
+ .. figure-mpl:: plot_directive/some_plots-1.png
42
+ :alt: bar
43
+ :srcset: plot_directive/some_plots-1.png,
44
+ plot_directive/some_plots-1.2x.png 2.00x
45
+ :class: plot-directive
46
+
47
+ The resulting html (at ``some_plots.html``) is::
48
+
49
+ <img src="sphx_glr_bar_001_hidpi.png"
50
+ srcset="_images/some_plot-1.png,
51
+ _images/some_plots-1.2x.png 2.00x",
52
+ alt="bar"
53
+ class="plot_directive" />
54
+
55
+ Note that the handling of subdirectories is different than that used by the sphinx
56
+ figure directive::
57
+
58
+ .. figure-mpl:: plot_directive/nestedpage/index-1.png
59
+ :alt: bar
60
+ :srcset: plot_directive/nestedpage/index-1.png
61
+ plot_directive/nestedpage/index-1.2x.png 2.00x
62
+ :class: plot_directive
63
+
64
+ The resulting html (at ``nestedpage/index.html``)::
65
+
66
+ <img src="../_images/nestedpage-index-1.png"
67
+ srcset="../_images/nestedpage-index-1.png,
68
+ ../_images/_images/nestedpage-index-1.2x.png 2.00x",
69
+ alt="bar"
70
+ class="sphx-glr-single-img" />
71
+
72
+ where the subdirectory is included in the image name for uniqueness.
73
+ """
74
+
75
+ has_content = False
76
+ required_arguments = 1
77
+ optional_arguments = 2
78
+ final_argument_whitespace = False
79
+ option_spec = {
80
+ 'alt': directives.unchanged,
81
+ 'height': directives.length_or_unitless,
82
+ 'width': directives.length_or_percentage_or_unitless,
83
+ 'scale': directives.nonnegative_int,
84
+ 'align': Image.align,
85
+ 'class': directives.class_option,
86
+ 'caption': directives.unchanged,
87
+ 'srcset': directives.unchanged,
88
+ }
89
+
90
+ def run(self):
91
+
92
+ image_node = figmplnode()
93
+
94
+ imagenm = self.arguments[0]
95
+ image_node['alt'] = self.options.get('alt', '')
96
+ image_node['align'] = self.options.get('align', None)
97
+ image_node['class'] = self.options.get('class', None)
98
+ image_node['width'] = self.options.get('width', None)
99
+ image_node['height'] = self.options.get('height', None)
100
+ image_node['scale'] = self.options.get('scale', None)
101
+ image_node['caption'] = self.options.get('caption', None)
102
+
103
+ # we would like uri to be the highest dpi version so that
104
+ # latex etc will use that. But for now, lets just make
105
+ # imagenm... maybe pdf one day?
106
+
107
+ image_node['uri'] = imagenm
108
+ image_node['srcset'] = self.options.get('srcset', None)
109
+
110
+ return [image_node]
111
+
112
+
113
+ def _parse_srcsetNodes(st):
114
+ """
115
+ parse srcset...
116
+ """
117
+ entries = st.split(',')
118
+ srcset = {}
119
+ for entry in entries:
120
+ spl = entry.strip().split(' ')
121
+ if len(spl) == 1:
122
+ srcset[0] = spl[0]
123
+ elif len(spl) == 2:
124
+ mult = spl[1][:-1]
125
+ srcset[float(mult)] = spl[0]
126
+ else:
127
+ raise ExtensionError(f'srcset argument "{entry}" is invalid.')
128
+ return srcset
129
+
130
+
131
+ def _copy_images_figmpl(self, node):
132
+
133
+ # these will be the temporary place the plot-directive put the images eg:
134
+ # ../../../build/html/plot_directive/users/explain/artists/index-1.png
135
+ if node['srcset']:
136
+ srcset = _parse_srcsetNodes(node['srcset'])
137
+ else:
138
+ srcset = None
139
+
140
+ # the rst file's location: eg /Users/username/matplotlib/doc/users/explain/artists
141
+ docsource = PurePath(self.document['source']).parent
142
+
143
+ # get the relpath relative to root:
144
+ srctop = self.builder.srcdir
145
+ rel = relpath(docsource, srctop).replace('.', '').replace(os.sep, '-')
146
+ if len(rel):
147
+ rel += '-'
148
+ # eg: users/explain/artists
149
+
150
+ imagedir = PurePath(self.builder.outdir, self.builder.imagedir)
151
+ # eg: /Users/username/matplotlib/doc/build/html/_images/users/explain/artists
152
+
153
+ Path(imagedir).mkdir(parents=True, exist_ok=True)
154
+
155
+ # copy all the sources to the imagedir:
156
+ if srcset:
157
+ for src in srcset.values():
158
+ # the entries in srcset are relative to docsource's directory
159
+ abspath = PurePath(docsource, src)
160
+ name = rel + abspath.name
161
+ shutil.copyfile(abspath, imagedir / name)
162
+ else:
163
+ abspath = PurePath(docsource, node['uri'])
164
+ name = rel + abspath.name
165
+ shutil.copyfile(abspath, imagedir / name)
166
+
167
+ return imagedir, srcset, rel
168
+
169
+
170
+ def visit_figmpl_html(self, node):
171
+
172
+ imagedir, srcset, rel = _copy_images_figmpl(self, node)
173
+
174
+ # /doc/examples/subd/plot_1.rst
175
+ docsource = PurePath(self.document['source'])
176
+ # /doc/
177
+ # make sure to add the trailing slash:
178
+ srctop = PurePath(self.builder.srcdir, '')
179
+ # examples/subd/plot_1.rst
180
+ relsource = relpath(docsource, srctop)
181
+ # /doc/build/html
182
+ desttop = PurePath(self.builder.outdir, '')
183
+ # /doc/build/html/examples/subd
184
+ dest = desttop / relsource
185
+
186
+ # ../../_images/ for dirhtml and ../_images/ for html
187
+ imagerel = PurePath(relpath(imagedir, dest.parent)).as_posix()
188
+ if self.builder.name == "dirhtml":
189
+ imagerel = f'..{imagerel}'
190
+
191
+ # make uri also be relative...
192
+ nm = PurePath(node['uri'][1:]).name
193
+ uri = f'{imagerel}/{rel}{nm}'
194
+ img_attrs = {'src': uri, 'alt': node['alt']}
195
+
196
+ # make srcset str. Need to change all the prefixes!
197
+ maxsrc = uri
198
+ if srcset:
199
+ maxmult = -1
200
+ srcsetst = ''
201
+ for mult, src in srcset.items():
202
+ nm = PurePath(src[1:]).name
203
+ # ../../_images/plot_1_2_0x.png
204
+ path = f'{imagerel}/{rel}{nm}'
205
+ srcsetst += path
206
+ if mult == 0:
207
+ srcsetst += ', '
208
+ else:
209
+ srcsetst += f' {mult:1.2f}x, '
210
+
211
+ if mult > maxmult:
212
+ maxmult = mult
213
+ maxsrc = path
214
+
215
+ # trim trailing comma and space...
216
+ img_attrs['srcset'] = srcsetst[:-2]
217
+
218
+ if node['class'] is not None:
219
+ img_attrs['class'] = ' '.join(node['class'])
220
+ for style in ['width', 'height', 'scale']:
221
+ if node[style]:
222
+ if 'style' not in img_attrs:
223
+ img_attrs['style'] = f'{style}: {node[style]};'
224
+ else:
225
+ img_attrs['style'] += f'{style}: {node[style]};'
226
+
227
+ # <figure class="align-default" id="id1">
228
+ # <a class="reference internal image-reference" href="_images/index-1.2x.png">
229
+ # <img alt="_images/index-1.2x.png"
230
+ # src="_images/index-1.2x.png" style="width: 53%;" />
231
+ # </a>
232
+ # <figcaption>
233
+ # <p><span class="caption-text">Figure caption is here....</span>
234
+ # <a class="headerlink" href="#id1" title="Permalink to this image">#</a></p>
235
+ # </figcaption>
236
+ # </figure>
237
+ self.body.append(
238
+ self.starttag(
239
+ node, 'figure',
240
+ CLASS=f'align-{node["align"]}' if node['align'] else 'align-center'))
241
+ self.body.append(
242
+ self.starttag(node, 'a', CLASS='reference internal image-reference',
243
+ href=maxsrc) +
244
+ self.emptytag(node, 'img', **img_attrs) +
245
+ '</a>\n')
246
+ if node['caption']:
247
+ self.body.append(self.starttag(node, 'figcaption'))
248
+ self.body.append(self.starttag(node, 'p'))
249
+ self.body.append(self.starttag(node, 'span', CLASS='caption-text'))
250
+ self.body.append(node['caption'])
251
+ self.body.append('</span></p></figcaption>\n')
252
+ self.body.append('</figure>\n')
253
+
254
+
255
+ def visit_figmpl_latex(self, node):
256
+
257
+ if node['srcset'] is not None:
258
+ imagedir, srcset = _copy_images_figmpl(self, node)
259
+ maxmult = -1
260
+ # choose the highest res version for latex:
261
+ maxmult = max(srcset, default=-1)
262
+ node['uri'] = PurePath(srcset[maxmult]).name
263
+
264
+ self.visit_figure(node)
265
+
266
+
267
+ def depart_figmpl_html(self, node):
268
+ pass
269
+
270
+
271
+ def depart_figmpl_latex(self, node):
272
+ self.depart_figure(node)
273
+
274
+
275
+ def figurempl_addnode(app):
276
+ app.add_node(figmplnode,
277
+ html=(visit_figmpl_html, depart_figmpl_html),
278
+ latex=(visit_figmpl_latex, depart_figmpl_latex))
279
+
280
+
281
+ def setup(app):
282
+ app.add_directive("figure-mpl", FigureMpl)
283
+ figurempl_addnode(app)
284
+ metadata = {'parallel_read_safe': True, 'parallel_write_safe': True,
285
+ 'version': matplotlib.__version__}
286
+ return metadata
lib/python3.12/site-packages/matplotlib/sphinxext/mathmpl.py ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ r"""
2
+ A role and directive to display mathtext in Sphinx
3
+ ==================================================
4
+
5
+ The ``mathmpl`` Sphinx extension creates a mathtext image in Matplotlib and
6
+ shows it in html output. Thus, it is a true and faithful representation of what
7
+ you will see if you pass a given LaTeX string to Matplotlib (see
8
+ :ref:`mathtext`).
9
+
10
+ .. warning::
11
+ In most cases, you will likely want to use one of `Sphinx's builtin Math
12
+ extensions
13
+ <https://www.sphinx-doc.org/en/master/usage/extensions/math.html>`__
14
+ instead of this one. The builtin Sphinx math directive uses MathJax to
15
+ render mathematical expressions, and addresses accessibility concerns that
16
+ ``mathmpl`` doesn't address.
17
+
18
+ Mathtext may be included in two ways:
19
+
20
+ 1. Inline, using the role::
21
+
22
+ This text uses inline math: :mathmpl:`\alpha > \beta`.
23
+
24
+ which produces:
25
+
26
+ This text uses inline math: :mathmpl:`\alpha > \beta`.
27
+
28
+ 2. Standalone, using the directive::
29
+
30
+ Here is some standalone math:
31
+
32
+ .. mathmpl::
33
+
34
+ \alpha > \beta
35
+
36
+ which produces:
37
+
38
+ Here is some standalone math:
39
+
40
+ .. mathmpl::
41
+
42
+ \alpha > \beta
43
+
44
+ Options
45
+ -------
46
+
47
+ The ``mathmpl`` role and directive both support the following options:
48
+
49
+ fontset : str, default: 'cm'
50
+ The font set to use when displaying math. See :rc:`mathtext.fontset`.
51
+
52
+ fontsize : float
53
+ The font size, in points. Defaults to the value from the extension
54
+ configuration option defined below.
55
+
56
+ Configuration options
57
+ ---------------------
58
+
59
+ The mathtext extension has the following configuration options:
60
+
61
+ mathmpl_fontsize : float, default: 10.0
62
+ Default font size, in points.
63
+
64
+ mathmpl_srcset : list of str, default: []
65
+ Additional image sizes to generate when embedding in HTML, to support
66
+ `responsive resolution images
67
+ <https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images>`__.
68
+ The list should contain additional x-descriptors (``'1.5x'``, ``'2x'``,
69
+ etc.) to generate (1x is the default and always included.)
70
+
71
+ """
72
+
73
+ import hashlib
74
+ from pathlib import Path
75
+
76
+ from docutils import nodes
77
+ from docutils.parsers.rst import Directive, directives
78
+ import sphinx
79
+ from sphinx.errors import ConfigError, ExtensionError
80
+
81
+ import matplotlib as mpl
82
+ from matplotlib import _api, mathtext
83
+ from matplotlib.rcsetup import validate_float_or_None
84
+
85
+
86
+ # Define LaTeX math node:
87
+ class latex_math(nodes.General, nodes.Element):
88
+ pass
89
+
90
+
91
+ def fontset_choice(arg):
92
+ return directives.choice(arg, mathtext.MathTextParser._font_type_mapping)
93
+
94
+
95
+ def math_role(role, rawtext, text, lineno, inliner,
96
+ options={}, content=[]):
97
+ i = rawtext.find('`')
98
+ latex = rawtext[i+1:-1]
99
+ node = latex_math(rawtext)
100
+ node['latex'] = latex
101
+ node['fontset'] = options.get('fontset', 'cm')
102
+ node['fontsize'] = options.get('fontsize',
103
+ setup.app.config.mathmpl_fontsize)
104
+ return [node], []
105
+ math_role.options = {'fontset': fontset_choice,
106
+ 'fontsize': validate_float_or_None}
107
+
108
+
109
+ class MathDirective(Directive):
110
+ """
111
+ The ``.. mathmpl::`` directive, as documented in the module's docstring.
112
+ """
113
+ has_content = True
114
+ required_arguments = 0
115
+ optional_arguments = 0
116
+ final_argument_whitespace = False
117
+ option_spec = {'fontset': fontset_choice,
118
+ 'fontsize': validate_float_or_None}
119
+
120
+ def run(self):
121
+ latex = ''.join(self.content)
122
+ node = latex_math(self.block_text)
123
+ node['latex'] = latex
124
+ node['fontset'] = self.options.get('fontset', 'cm')
125
+ node['fontsize'] = self.options.get('fontsize',
126
+ setup.app.config.mathmpl_fontsize)
127
+ return [node]
128
+
129
+
130
+ # This uses mathtext to render the expression
131
+ def latex2png(latex, filename, fontset='cm', fontsize=10, dpi=100):
132
+ with mpl.rc_context({'mathtext.fontset': fontset, 'font.size': fontsize}):
133
+ try:
134
+ depth = mathtext.math_to_image(
135
+ f"${latex}$", filename, dpi=dpi, format="png")
136
+ except Exception:
137
+ _api.warn_external(f"Could not render math expression {latex}")
138
+ depth = 0
139
+ return depth
140
+
141
+
142
+ # LaTeX to HTML translation stuff:
143
+ def latex2html(node, source):
144
+ inline = isinstance(node.parent, nodes.TextElement)
145
+ latex = node['latex']
146
+ fontset = node['fontset']
147
+ fontsize = node['fontsize']
148
+ name = 'math-{}'.format(
149
+ hashlib.sha256(
150
+ f'{latex}{fontset}{fontsize}'.encode(),
151
+ usedforsecurity=False,
152
+ ).hexdigest()[-10:])
153
+
154
+ destdir = Path(setup.app.builder.outdir, '_images', 'mathmpl')
155
+ destdir.mkdir(parents=True, exist_ok=True)
156
+
157
+ dest = destdir / f'{name}.png'
158
+ depth = latex2png(latex, dest, fontset, fontsize=fontsize)
159
+
160
+ srcset = []
161
+ for size in setup.app.config.mathmpl_srcset:
162
+ filename = f'{name}-{size.replace(".", "_")}.png'
163
+ latex2png(latex, destdir / filename, fontset, fontsize=fontsize,
164
+ dpi=100 * float(size[:-1]))
165
+ srcset.append(
166
+ f'{setup.app.builder.imgpath}/mathmpl/{filename} {size}')
167
+ if srcset:
168
+ srcset = (f'srcset="{setup.app.builder.imgpath}/mathmpl/{name}.png, ' +
169
+ ', '.join(srcset) + '" ')
170
+
171
+ if inline:
172
+ cls = ''
173
+ else:
174
+ cls = 'class="center" '
175
+ if inline and depth != 0:
176
+ style = 'style="position: relative; bottom: -%dpx"' % (depth + 1)
177
+ else:
178
+ style = ''
179
+
180
+ return (f'<img src="{setup.app.builder.imgpath}/mathmpl/{name}.png"'
181
+ f' {srcset}{cls}{style}/>')
182
+
183
+
184
+ def _config_inited(app, config):
185
+ # Check for srcset hidpi images
186
+ for i, size in enumerate(app.config.mathmpl_srcset):
187
+ if size[-1] == 'x': # "2x" = "2.0"
188
+ try:
189
+ float(size[:-1])
190
+ except ValueError:
191
+ raise ConfigError(
192
+ f'Invalid value for mathmpl_srcset parameter: {size!r}. '
193
+ 'Must be a list of strings with the multiplicative '
194
+ 'factor followed by an "x". e.g. ["2.0x", "1.5x"]')
195
+ else:
196
+ raise ConfigError(
197
+ f'Invalid value for mathmpl_srcset parameter: {size!r}. '
198
+ 'Must be a list of strings with the multiplicative '
199
+ 'factor followed by an "x". e.g. ["2.0x", "1.5x"]')
200
+
201
+
202
+ def setup(app):
203
+ setup.app = app
204
+ app.add_config_value('mathmpl_fontsize', 10.0, True)
205
+ app.add_config_value('mathmpl_srcset', [], True)
206
+ try:
207
+ app.connect('config-inited', _config_inited) # Sphinx 1.8+
208
+ except ExtensionError:
209
+ app.connect('env-updated', lambda app, env: _config_inited(app, None))
210
+
211
+ # Add visit/depart methods to HTML-Translator:
212
+ def visit_latex_math_html(self, node):
213
+ source = self.document.attributes['source']
214
+ self.body.append(latex2html(node, source))
215
+
216
+ def depart_latex_math_html(self, node):
217
+ pass
218
+
219
+ # Add visit/depart methods to LaTeX-Translator:
220
+ def visit_latex_math_latex(self, node):
221
+ inline = isinstance(node.parent, nodes.TextElement)
222
+ if inline:
223
+ self.body.append('$%s$' % node['latex'])
224
+ else:
225
+ self.body.extend(['\\begin{equation}',
226
+ node['latex'],
227
+ '\\end{equation}'])
228
+
229
+ def depart_latex_math_latex(self, node):
230
+ pass
231
+
232
+ app.add_node(latex_math,
233
+ html=(visit_latex_math_html, depart_latex_math_html),
234
+ latex=(visit_latex_math_latex, depart_latex_math_latex))
235
+ app.add_role('mathmpl', math_role)
236
+ app.add_directive('mathmpl', MathDirective)
237
+ if sphinx.version_info < (1, 8):
238
+ app.add_role('math', math_role)
239
+ app.add_directive('math', MathDirective)
240
+
241
+ metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
242
+ return metadata
lib/python3.12/site-packages/matplotlib/sphinxext/plot_directive.py ADDED
@@ -0,0 +1,936 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ A directive for including a Matplotlib plot in a Sphinx document
3
+ ================================================================
4
+
5
+ This is a Sphinx extension providing a reStructuredText directive
6
+ ``.. plot::`` for including a plot in a Sphinx document.
7
+
8
+ In HTML output, ``.. plot::`` will include a .png file with a link
9
+ to a high-res .png and .pdf. In LaTeX output, it will include a .pdf.
10
+
11
+ The plot content may be defined in one of three ways:
12
+
13
+ 1. **A path to a source file** as the argument to the directive::
14
+
15
+ .. plot:: path/to/plot.py
16
+
17
+ When a path to a source file is given, the content of the
18
+ directive may optionally contain a caption for the plot::
19
+
20
+ .. plot:: path/to/plot.py
21
+
22
+ The plot caption.
23
+
24
+ Additionally, one may specify the name of a function to call (with
25
+ no arguments) immediately after importing the module::
26
+
27
+ .. plot:: path/to/plot.py plot_function1
28
+
29
+ 2. Included as **inline content** to the directive::
30
+
31
+ .. plot::
32
+
33
+ import matplotlib.pyplot as plt
34
+ plt.plot([1, 2, 3], [4, 5, 6])
35
+ plt.title("A plotting exammple")
36
+
37
+ 3. Using **doctest** syntax::
38
+
39
+ .. plot::
40
+
41
+ A plotting example:
42
+ >>> import matplotlib.pyplot as plt
43
+ >>> plt.plot([1, 2, 3], [4, 5, 6])
44
+
45
+ Options
46
+ -------
47
+
48
+ The ``.. plot::`` directive supports the following options:
49
+
50
+ ``:format:`` : {'python', 'doctest'}
51
+ The format of the input. If unset, the format is auto-detected.
52
+
53
+ ``:include-source:`` : bool
54
+ Whether to display the source code. The default can be changed using
55
+ the ``plot_include_source`` variable in :file:`conf.py` (which itself
56
+ defaults to False).
57
+
58
+ ``:show-source-link:`` : bool
59
+ Whether to show a link to the source in HTML. The default can be
60
+ changed using the ``plot_html_show_source_link`` variable in
61
+ :file:`conf.py` (which itself defaults to True).
62
+
63
+ ``:context:`` : bool or str
64
+ If provided, the code will be run in the context of all previous plot
65
+ directives for which the ``:context:`` option was specified. This only
66
+ applies to inline code plot directives, not those run from files. If
67
+ the ``:context: reset`` option is specified, the context is reset
68
+ for this and future plots, and previous figures are closed prior to
69
+ running the code. ``:context: close-figs`` keeps the context but closes
70
+ previous figures before running the code.
71
+
72
+ ``:nofigs:`` : bool
73
+ If specified, the code block will be run, but no figures will be
74
+ inserted. This is usually useful with the ``:context:`` option.
75
+
76
+ ``:caption:`` : str
77
+ If specified, the option's argument will be used as a caption for the
78
+ figure. This overwrites the caption given in the content, when the plot
79
+ is generated from a file.
80
+
81
+ Additionally, this directive supports all the options of the `image directive
82
+ <https://docutils.sourceforge.io/docs/ref/rst/directives.html#image>`_,
83
+ except for ``:target:`` (since plot will add its own target). These include
84
+ ``:alt:``, ``:height:``, ``:width:``, ``:scale:``, ``:align:`` and ``:class:``.
85
+
86
+ Configuration options
87
+ ---------------------
88
+
89
+ The plot directive has the following configuration options:
90
+
91
+ plot_include_source
92
+ Default value for the include-source option (default: False).
93
+
94
+ plot_html_show_source_link
95
+ Whether to show a link to the source in HTML (default: True).
96
+
97
+ plot_pre_code
98
+ Code that should be executed before each plot. If None (the default),
99
+ it will default to a string containing::
100
+
101
+ import numpy as np
102
+ from matplotlib import pyplot as plt
103
+
104
+ plot_basedir
105
+ Base directory, to which ``plot::`` file names are relative to.
106
+ If None or empty (the default), file names are relative to the
107
+ directory where the file containing the directive is.
108
+
109
+ plot_formats
110
+ File formats to generate (default: ['png', 'hires.png', 'pdf']).
111
+ List of tuples or strings::
112
+
113
+ [(suffix, dpi), suffix, ...]
114
+
115
+ that determine the file format and the DPI. For entries whose
116
+ DPI was omitted, sensible defaults are chosen. When passing from
117
+ the command line through sphinx_build the list should be passed as
118
+ suffix:dpi,suffix:dpi, ...
119
+
120
+ plot_html_show_formats
121
+ Whether to show links to the files in HTML (default: True).
122
+
123
+ plot_rcparams
124
+ A dictionary containing any non-standard rcParams that should
125
+ be applied before each plot (default: {}).
126
+
127
+ plot_apply_rcparams
128
+ By default, rcParams are applied when ``:context:`` option is not used
129
+ in a plot directive. If set, this configuration option overrides this
130
+ behavior and applies rcParams before each plot.
131
+
132
+ plot_working_directory
133
+ By default, the working directory will be changed to the directory of
134
+ the example, so the code can get at its data files, if any. Also its
135
+ path will be added to `sys.path` so it can import any helper modules
136
+ sitting beside it. This configuration option can be used to specify
137
+ a central directory (also added to `sys.path`) where data files and
138
+ helper modules for all code are located.
139
+
140
+ plot_template
141
+ Provide a customized template for preparing restructured text.
142
+
143
+ plot_srcset
144
+ Allow the srcset image option for responsive image resolutions. List of
145
+ strings with the multiplicative factors followed by an "x".
146
+ e.g. ["2.0x", "1.5x"]. "2.0x" will create a png with the default "png"
147
+ resolution from plot_formats, multiplied by 2. If plot_srcset is
148
+ specified, the plot directive uses the
149
+ :doc:`/api/sphinxext_figmpl_directive_api` (instead of the usual figure
150
+ directive) in the intermediary rst file that is generated.
151
+ The plot_srcset option is incompatible with *singlehtml* builds, and an
152
+ error will be raised.
153
+
154
+ Notes on how it works
155
+ ---------------------
156
+
157
+ The plot directive runs the code it is given, either in the source file or the
158
+ code under the directive. The figure created (if any) is saved in the sphinx
159
+ build directory under a subdirectory named ``plot_directive``. It then creates
160
+ an intermediate rst file that calls a ``.. figure:`` directive (or
161
+ ``.. figmpl::`` directive if ``plot_srcset`` is being used) and has links to
162
+ the ``*.png`` files in the ``plot_directive`` directory. These translations can
163
+ be customized by changing the *plot_template*. See the source of
164
+ :doc:`/api/sphinxext_plot_directive_api` for the templates defined in *TEMPLATE*
165
+ and *TEMPLATE_SRCSET*.
166
+ """
167
+
168
+ import contextlib
169
+ import doctest
170
+ from io import StringIO
171
+ import itertools
172
+ import os
173
+ from os.path import relpath
174
+ from pathlib import Path
175
+ import re
176
+ import shutil
177
+ import sys
178
+ import textwrap
179
+ import traceback
180
+
181
+ from docutils.parsers.rst import directives, Directive
182
+ from docutils.parsers.rst.directives.images import Image
183
+ import jinja2 # Sphinx dependency.
184
+
185
+ from sphinx.errors import ExtensionError
186
+
187
+ import matplotlib
188
+ from matplotlib.backend_bases import FigureManagerBase
189
+ import matplotlib.pyplot as plt
190
+ from matplotlib import _pylab_helpers, cbook
191
+
192
+ matplotlib.use("agg")
193
+
194
+ __version__ = 2
195
+
196
+
197
+ # -----------------------------------------------------------------------------
198
+ # Registration hook
199
+ # -----------------------------------------------------------------------------
200
+
201
+
202
+ def _option_boolean(arg):
203
+ if not arg or not arg.strip():
204
+ # no argument given, assume used as a flag
205
+ return True
206
+ elif arg.strip().lower() in ('no', '0', 'false'):
207
+ return False
208
+ elif arg.strip().lower() in ('yes', '1', 'true'):
209
+ return True
210
+ else:
211
+ raise ValueError(f'{arg!r} unknown boolean')
212
+
213
+
214
+ def _option_context(arg):
215
+ if arg in [None, 'reset', 'close-figs']:
216
+ return arg
217
+ raise ValueError("Argument should be None or 'reset' or 'close-figs'")
218
+
219
+
220
+ def _option_format(arg):
221
+ return directives.choice(arg, ('python', 'doctest'))
222
+
223
+
224
+ def mark_plot_labels(app, document):
225
+ """
226
+ To make plots referenceable, we need to move the reference from the
227
+ "htmlonly" (or "latexonly") node to the actual figure node itself.
228
+ """
229
+ for name, explicit in document.nametypes.items():
230
+ if not explicit:
231
+ continue
232
+ labelid = document.nameids[name]
233
+ if labelid is None:
234
+ continue
235
+ node = document.ids[labelid]
236
+ if node.tagname in ('html_only', 'latex_only'):
237
+ for n in node:
238
+ if n.tagname == 'figure':
239
+ sectname = name
240
+ for c in n:
241
+ if c.tagname == 'caption':
242
+ sectname = c.astext()
243
+ break
244
+
245
+ node['ids'].remove(labelid)
246
+ node['names'].remove(name)
247
+ n['ids'].append(labelid)
248
+ n['names'].append(name)
249
+ document.settings.env.labels[name] = \
250
+ document.settings.env.docname, labelid, sectname
251
+ break
252
+
253
+
254
+ class PlotDirective(Directive):
255
+ """The ``.. plot::`` directive, as documented in the module's docstring."""
256
+
257
+ has_content = True
258
+ required_arguments = 0
259
+ optional_arguments = 2
260
+ final_argument_whitespace = False
261
+ option_spec = {
262
+ 'alt': directives.unchanged,
263
+ 'height': directives.length_or_unitless,
264
+ 'width': directives.length_or_percentage_or_unitless,
265
+ 'scale': directives.nonnegative_int,
266
+ 'align': Image.align,
267
+ 'class': directives.class_option,
268
+ 'include-source': _option_boolean,
269
+ 'show-source-link': _option_boolean,
270
+ 'format': _option_format,
271
+ 'context': _option_context,
272
+ 'nofigs': directives.flag,
273
+ 'caption': directives.unchanged,
274
+ }
275
+
276
+ def run(self):
277
+ """Run the plot directive."""
278
+ try:
279
+ return run(self.arguments, self.content, self.options,
280
+ self.state_machine, self.state, self.lineno)
281
+ except Exception as e:
282
+ raise self.error(str(e))
283
+
284
+
285
+ def _copy_css_file(app, exc):
286
+ if exc is None and app.builder.format == 'html':
287
+ src = cbook._get_data_path('plot_directive/plot_directive.css')
288
+ dst = app.outdir / Path('_static')
289
+ dst.mkdir(exist_ok=True)
290
+ # Use copyfile because we do not want to copy src's permissions.
291
+ shutil.copyfile(src, dst / Path('plot_directive.css'))
292
+
293
+
294
+ def setup(app):
295
+ setup.app = app
296
+ setup.config = app.config
297
+ setup.confdir = app.confdir
298
+ app.add_directive('plot', PlotDirective)
299
+ app.add_config_value('plot_pre_code', None, True)
300
+ app.add_config_value('plot_include_source', False, True)
301
+ app.add_config_value('plot_html_show_source_link', True, True)
302
+ app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True)
303
+ app.add_config_value('plot_basedir', None, True)
304
+ app.add_config_value('plot_html_show_formats', True, True)
305
+ app.add_config_value('plot_rcparams', {}, True)
306
+ app.add_config_value('plot_apply_rcparams', False, True)
307
+ app.add_config_value('plot_working_directory', None, True)
308
+ app.add_config_value('plot_template', None, True)
309
+ app.add_config_value('plot_srcset', [], True)
310
+ app.connect('doctree-read', mark_plot_labels)
311
+ app.add_css_file('plot_directive.css')
312
+ app.connect('build-finished', _copy_css_file)
313
+ metadata = {'parallel_read_safe': True, 'parallel_write_safe': True,
314
+ 'version': matplotlib.__version__}
315
+ return metadata
316
+
317
+
318
+ # -----------------------------------------------------------------------------
319
+ # Doctest handling
320
+ # -----------------------------------------------------------------------------
321
+
322
+
323
+ def contains_doctest(text):
324
+ try:
325
+ # check if it's valid Python as-is
326
+ compile(text, '<string>', 'exec')
327
+ return False
328
+ except SyntaxError:
329
+ pass
330
+ r = re.compile(r'^\s*>>>', re.M)
331
+ m = r.search(text)
332
+ return bool(m)
333
+
334
+
335
+ def _split_code_at_show(text, function_name):
336
+ """Split code at plt.show()."""
337
+
338
+ is_doctest = contains_doctest(text)
339
+ if function_name is None:
340
+ parts = []
341
+ part = []
342
+ for line in text.split("\n"):
343
+ if ((not is_doctest and line.startswith('plt.show(')) or
344
+ (is_doctest and line.strip() == '>>> plt.show()')):
345
+ part.append(line)
346
+ parts.append("\n".join(part))
347
+ part = []
348
+ else:
349
+ part.append(line)
350
+ if "\n".join(part).strip():
351
+ parts.append("\n".join(part))
352
+ else:
353
+ parts = [text]
354
+ return is_doctest, parts
355
+
356
+
357
+ # -----------------------------------------------------------------------------
358
+ # Template
359
+ # -----------------------------------------------------------------------------
360
+
361
+ _SOURCECODE = """
362
+ {{ source_code }}
363
+
364
+ .. only:: html
365
+
366
+ {% if src_name or (html_show_formats and not multi_image) %}
367
+ (
368
+ {%- if src_name -%}
369
+ :download:`Source code <{{ build_dir }}/{{ src_name }}>`
370
+ {%- endif -%}
371
+ {%- if html_show_formats and not multi_image -%}
372
+ {%- for img in images -%}
373
+ {%- for fmt in img.formats -%}
374
+ {%- if src_name or not loop.first -%}, {% endif -%}
375
+ :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>`
376
+ {%- endfor -%}
377
+ {%- endfor -%}
378
+ {%- endif -%}
379
+ )
380
+ {% endif %}
381
+ """
382
+
383
+ TEMPLATE_SRCSET = _SOURCECODE + """
384
+ {% for img in images %}
385
+ .. figure-mpl:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
386
+ {% for option in options -%}
387
+ {{ option }}
388
+ {% endfor %}
389
+ {%- if caption -%}
390
+ {{ caption }} {# appropriate leading whitespace added beforehand #}
391
+ {% endif -%}
392
+ {%- if srcset -%}
393
+ :srcset: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
394
+ {%- for sr in srcset -%}
395
+ , {{ build_dir }}/{{ img.basename }}.{{ sr }}.{{ default_fmt }} {{sr}}
396
+ {%- endfor -%}
397
+ {% endif %}
398
+
399
+ {% if html_show_formats and multi_image %}
400
+ (
401
+ {%- for fmt in img.formats -%}
402
+ {%- if not loop.first -%}, {% endif -%}
403
+ :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>`
404
+ {%- endfor -%}
405
+ )
406
+ {% endif %}
407
+
408
+
409
+ {% endfor %}
410
+
411
+ .. only:: not html
412
+
413
+ {% for img in images %}
414
+ .. figure-mpl:: {{ build_dir }}/{{ img.basename }}.*
415
+ {% for option in options -%}
416
+ {{ option }}
417
+ {% endfor -%}
418
+
419
+ {{ caption }} {# appropriate leading whitespace added beforehand #}
420
+ {% endfor %}
421
+
422
+ """
423
+
424
+ TEMPLATE = _SOURCECODE + """
425
+
426
+ {% for img in images %}
427
+ .. figure:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
428
+ {% for option in options -%}
429
+ {{ option }}
430
+ {% endfor %}
431
+
432
+ {% if html_show_formats and multi_image -%}
433
+ (
434
+ {%- for fmt in img.formats -%}
435
+ {%- if not loop.first -%}, {% endif -%}
436
+ :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>`
437
+ {%- endfor -%}
438
+ )
439
+ {%- endif -%}
440
+
441
+ {{ caption }} {# appropriate leading whitespace added beforehand #}
442
+ {% endfor %}
443
+
444
+ .. only:: not html
445
+
446
+ {% for img in images %}
447
+ .. figure:: {{ build_dir }}/{{ img.basename }}.*
448
+ {% for option in options -%}
449
+ {{ option }}
450
+ {% endfor -%}
451
+
452
+ {{ caption }} {# appropriate leading whitespace added beforehand #}
453
+ {% endfor %}
454
+
455
+ """
456
+
457
+ exception_template = """
458
+ .. only:: html
459
+
460
+ [`source code <%(linkdir)s/%(basename)s.py>`__]
461
+
462
+ Exception occurred rendering plot.
463
+
464
+ """
465
+
466
+ # the context of the plot for all directives specified with the
467
+ # :context: option
468
+ plot_context = dict()
469
+
470
+
471
+ class ImageFile:
472
+ def __init__(self, basename, dirname):
473
+ self.basename = basename
474
+ self.dirname = dirname
475
+ self.formats = []
476
+
477
+ def filename(self, format):
478
+ return os.path.join(self.dirname, f"{self.basename}.{format}")
479
+
480
+ def filenames(self):
481
+ return [self.filename(fmt) for fmt in self.formats]
482
+
483
+
484
+ def out_of_date(original, derived, includes=None):
485
+ """
486
+ Return whether *derived* is out-of-date relative to *original* or any of
487
+ the RST files included in it using the RST include directive (*includes*).
488
+ *derived* and *original* are full paths, and *includes* is optionally a
489
+ list of full paths which may have been included in the *original*.
490
+ """
491
+ if not os.path.exists(derived):
492
+ return True
493
+
494
+ if includes is None:
495
+ includes = []
496
+ files_to_check = [original, *includes]
497
+
498
+ def out_of_date_one(original, derived_mtime):
499
+ return (os.path.exists(original) and
500
+ derived_mtime < os.stat(original).st_mtime)
501
+
502
+ derived_mtime = os.stat(derived).st_mtime
503
+ return any(out_of_date_one(f, derived_mtime) for f in files_to_check)
504
+
505
+
506
+ class PlotError(RuntimeError):
507
+ pass
508
+
509
+
510
+ def _run_code(code, code_path, ns=None, function_name=None):
511
+ """
512
+ Import a Python module from a path, and run the function given by
513
+ name, if function_name is not None.
514
+ """
515
+
516
+ # Change the working directory to the directory of the example, so
517
+ # it can get at its data files, if any. Add its path to sys.path
518
+ # so it can import any helper modules sitting beside it.
519
+ pwd = os.getcwd()
520
+ if setup.config.plot_working_directory is not None:
521
+ try:
522
+ os.chdir(setup.config.plot_working_directory)
523
+ except OSError as err:
524
+ raise OSError(f'{err}\n`plot_working_directory` option in '
525
+ f'Sphinx configuration file must be a valid '
526
+ f'directory path') from err
527
+ except TypeError as err:
528
+ raise TypeError(f'{err}\n`plot_working_directory` option in '
529
+ f'Sphinx configuration file must be a string or '
530
+ f'None') from err
531
+ elif code_path is not None:
532
+ dirname = os.path.abspath(os.path.dirname(code_path))
533
+ os.chdir(dirname)
534
+
535
+ with cbook._setattr_cm(
536
+ sys, argv=[code_path], path=[os.getcwd(), *sys.path]), \
537
+ contextlib.redirect_stdout(StringIO()):
538
+ try:
539
+ if ns is None:
540
+ ns = {}
541
+ if not ns:
542
+ if setup.config.plot_pre_code is None:
543
+ exec('import numpy as np\n'
544
+ 'from matplotlib import pyplot as plt\n', ns)
545
+ else:
546
+ exec(str(setup.config.plot_pre_code), ns)
547
+ if "__main__" in code:
548
+ ns['__name__'] = '__main__'
549
+
550
+ # Patch out non-interactive show() to avoid triggering a warning.
551
+ with cbook._setattr_cm(FigureManagerBase, show=lambda self: None):
552
+ exec(code, ns)
553
+ if function_name is not None:
554
+ exec(function_name + "()", ns)
555
+
556
+ except (Exception, SystemExit) as err:
557
+ raise PlotError(traceback.format_exc()) from err
558
+ finally:
559
+ os.chdir(pwd)
560
+ return ns
561
+
562
+
563
+ def clear_state(plot_rcparams, close=True):
564
+ if close:
565
+ plt.close('all')
566
+ matplotlib.rc_file_defaults()
567
+ matplotlib.rcParams.update(plot_rcparams)
568
+
569
+
570
+ def get_plot_formats(config):
571
+ default_dpi = {'png': 80, 'hires.png': 200, 'pdf': 200}
572
+ formats = []
573
+ plot_formats = config.plot_formats
574
+ for fmt in plot_formats:
575
+ if isinstance(fmt, str):
576
+ if ':' in fmt:
577
+ suffix, dpi = fmt.split(':')
578
+ formats.append((str(suffix), int(dpi)))
579
+ else:
580
+ formats.append((fmt, default_dpi.get(fmt, 80)))
581
+ elif isinstance(fmt, (tuple, list)) and len(fmt) == 2:
582
+ formats.append((str(fmt[0]), int(fmt[1])))
583
+ else:
584
+ raise PlotError('invalid image format "%r" in plot_formats' % fmt)
585
+ return formats
586
+
587
+
588
+ def _parse_srcset(entries):
589
+ """
590
+ Parse srcset for multiples...
591
+ """
592
+ srcset = {}
593
+ for entry in entries:
594
+ entry = entry.strip()
595
+ if len(entry) >= 2:
596
+ mult = entry[:-1]
597
+ srcset[float(mult)] = entry
598
+ else:
599
+ raise ExtensionError(f'srcset argument {entry!r} is invalid.')
600
+ return srcset
601
+
602
+
603
+ def render_figures(code, code_path, output_dir, output_base, context,
604
+ function_name, config, context_reset=False,
605
+ close_figs=False,
606
+ code_includes=None):
607
+ """
608
+ Run a pyplot script and save the images in *output_dir*.
609
+
610
+ Save the images under *output_dir* with file names derived from
611
+ *output_base*
612
+ """
613
+
614
+ if function_name is not None:
615
+ output_base = f'{output_base}_{function_name}'
616
+ formats = get_plot_formats(config)
617
+
618
+ # Try to determine if all images already exist
619
+
620
+ is_doctest, code_pieces = _split_code_at_show(code, function_name)
621
+ # Look for single-figure output files first
622
+ img = ImageFile(output_base, output_dir)
623
+ for format, dpi in formats:
624
+ if context or out_of_date(code_path, img.filename(format),
625
+ includes=code_includes):
626
+ all_exists = False
627
+ break
628
+ img.formats.append(format)
629
+ else:
630
+ all_exists = True
631
+
632
+ if all_exists:
633
+ return [(code, [img])]
634
+
635
+ # Then look for multi-figure output files
636
+ results = []
637
+ for i, code_piece in enumerate(code_pieces):
638
+ images = []
639
+ for j in itertools.count():
640
+ if len(code_pieces) > 1:
641
+ img = ImageFile('%s_%02d_%02d' % (output_base, i, j),
642
+ output_dir)
643
+ else:
644
+ img = ImageFile('%s_%02d' % (output_base, j), output_dir)
645
+ for fmt, dpi in formats:
646
+ if context or out_of_date(code_path, img.filename(fmt),
647
+ includes=code_includes):
648
+ all_exists = False
649
+ break
650
+ img.formats.append(fmt)
651
+
652
+ # assume that if we have one, we have them all
653
+ if not all_exists:
654
+ all_exists = (j > 0)
655
+ break
656
+ images.append(img)
657
+ if not all_exists:
658
+ break
659
+ results.append((code_piece, images))
660
+ else:
661
+ all_exists = True
662
+
663
+ if all_exists:
664
+ return results
665
+
666
+ # We didn't find the files, so build them
667
+
668
+ results = []
669
+ ns = plot_context if context else {}
670
+
671
+ if context_reset:
672
+ clear_state(config.plot_rcparams)
673
+ plot_context.clear()
674
+
675
+ close_figs = not context or close_figs
676
+
677
+ for i, code_piece in enumerate(code_pieces):
678
+
679
+ if not context or config.plot_apply_rcparams:
680
+ clear_state(config.plot_rcparams, close_figs)
681
+ elif close_figs:
682
+ plt.close('all')
683
+
684
+ _run_code(doctest.script_from_examples(code_piece) if is_doctest
685
+ else code_piece,
686
+ code_path, ns, function_name)
687
+
688
+ images = []
689
+ fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()
690
+ for j, figman in enumerate(fig_managers):
691
+ if len(fig_managers) == 1 and len(code_pieces) == 1:
692
+ img = ImageFile(output_base, output_dir)
693
+ elif len(code_pieces) == 1:
694
+ img = ImageFile("%s_%02d" % (output_base, j), output_dir)
695
+ else:
696
+ img = ImageFile("%s_%02d_%02d" % (output_base, i, j),
697
+ output_dir)
698
+ images.append(img)
699
+
700
+ for fmt, dpi in formats:
701
+ try:
702
+ figman.canvas.figure.savefig(img.filename(fmt), dpi=dpi)
703
+ if fmt == formats[0][0] and config.plot_srcset:
704
+ # save a 2x, 3x etc version of the default...
705
+ srcset = _parse_srcset(config.plot_srcset)
706
+ for mult, suffix in srcset.items():
707
+ fm = f'{suffix}.{fmt}'
708
+ img.formats.append(fm)
709
+ figman.canvas.figure.savefig(img.filename(fm),
710
+ dpi=int(dpi * mult))
711
+ except Exception as err:
712
+ raise PlotError(traceback.format_exc()) from err
713
+ img.formats.append(fmt)
714
+
715
+ results.append((code_piece, images))
716
+
717
+ if not context or config.plot_apply_rcparams:
718
+ clear_state(config.plot_rcparams, close=not context)
719
+
720
+ return results
721
+
722
+
723
+ def run(arguments, content, options, state_machine, state, lineno):
724
+ document = state_machine.document
725
+ config = document.settings.env.config
726
+ nofigs = 'nofigs' in options
727
+
728
+ if config.plot_srcset and setup.app.builder.name == 'singlehtml':
729
+ raise ExtensionError(
730
+ 'plot_srcset option not compatible with single HTML writer')
731
+
732
+ formats = get_plot_formats(config)
733
+ default_fmt = formats[0][0]
734
+
735
+ options.setdefault('include-source', config.plot_include_source)
736
+ options.setdefault('show-source-link', config.plot_html_show_source_link)
737
+
738
+ if 'class' in options:
739
+ # classes are parsed into a list of string, and output by simply
740
+ # printing the list, abusing the fact that RST guarantees to strip
741
+ # non-conforming characters
742
+ options['class'] = ['plot-directive'] + options['class']
743
+ else:
744
+ options.setdefault('class', ['plot-directive'])
745
+ keep_context = 'context' in options
746
+ context_opt = None if not keep_context else options['context']
747
+
748
+ rst_file = document.attributes['source']
749
+ rst_dir = os.path.dirname(rst_file)
750
+
751
+ if len(arguments):
752
+ if not config.plot_basedir:
753
+ source_file_name = os.path.join(setup.app.builder.srcdir,
754
+ directives.uri(arguments[0]))
755
+ else:
756
+ source_file_name = os.path.join(setup.confdir, config.plot_basedir,
757
+ directives.uri(arguments[0]))
758
+ # If there is content, it will be passed as a caption.
759
+ caption = '\n'.join(content)
760
+
761
+ # Enforce unambiguous use of captions.
762
+ if "caption" in options:
763
+ if caption:
764
+ raise ValueError(
765
+ 'Caption specified in both content and options.'
766
+ ' Please remove ambiguity.'
767
+ )
768
+ # Use caption option
769
+ caption = options["caption"]
770
+
771
+ # If the optional function name is provided, use it
772
+ if len(arguments) == 2:
773
+ function_name = arguments[1]
774
+ else:
775
+ function_name = None
776
+
777
+ code = Path(source_file_name).read_text(encoding='utf-8')
778
+ output_base = os.path.basename(source_file_name)
779
+ else:
780
+ source_file_name = rst_file
781
+ code = textwrap.dedent("\n".join(map(str, content)))
782
+ counter = document.attributes.get('_plot_counter', 0) + 1
783
+ document.attributes['_plot_counter'] = counter
784
+ base, ext = os.path.splitext(os.path.basename(source_file_name))
785
+ output_base = '%s-%d.py' % (base, counter)
786
+ function_name = None
787
+ caption = options.get('caption', '')
788
+
789
+ base, source_ext = os.path.splitext(output_base)
790
+ if source_ext in ('.py', '.rst', '.txt'):
791
+ output_base = base
792
+ else:
793
+ source_ext = ''
794
+
795
+ # ensure that LaTeX includegraphics doesn't choke in foo.bar.pdf filenames
796
+ output_base = output_base.replace('.', '-')
797
+
798
+ # is it in doctest format?
799
+ is_doctest = contains_doctest(code)
800
+ if 'format' in options:
801
+ if options['format'] == 'python':
802
+ is_doctest = False
803
+ else:
804
+ is_doctest = True
805
+
806
+ # determine output directory name fragment
807
+ source_rel_name = relpath(source_file_name, setup.confdir)
808
+ source_rel_dir = os.path.dirname(source_rel_name).lstrip(os.path.sep)
809
+
810
+ # build_dir: where to place output files (temporarily)
811
+ build_dir = os.path.join(os.path.dirname(setup.app.doctreedir),
812
+ 'plot_directive',
813
+ source_rel_dir)
814
+ # get rid of .. in paths, also changes pathsep
815
+ # see note in Python docs for warning about symbolic links on Windows.
816
+ # need to compare source and dest paths at end
817
+ build_dir = os.path.normpath(build_dir)
818
+ os.makedirs(build_dir, exist_ok=True)
819
+
820
+ # how to link to files from the RST file
821
+ try:
822
+ build_dir_link = relpath(build_dir, rst_dir).replace(os.path.sep, '/')
823
+ except ValueError:
824
+ # on Windows, relpath raises ValueError when path and start are on
825
+ # different mounts/drives
826
+ build_dir_link = build_dir
827
+
828
+ # get list of included rst files so that the output is updated when any
829
+ # plots in the included files change. These attributes are modified by the
830
+ # include directive (see the docutils.parsers.rst.directives.misc module).
831
+ try:
832
+ source_file_includes = [os.path.join(os.getcwd(), t[0])
833
+ for t in state.document.include_log]
834
+ except AttributeError:
835
+ # the document.include_log attribute only exists in docutils >=0.17,
836
+ # before that we need to inspect the state machine
837
+ possible_sources = {os.path.join(setup.confdir, t[0])
838
+ for t in state_machine.input_lines.items}
839
+ source_file_includes = [f for f in possible_sources
840
+ if os.path.isfile(f)]
841
+ # remove the source file itself from the includes
842
+ try:
843
+ source_file_includes.remove(source_file_name)
844
+ except ValueError:
845
+ pass
846
+
847
+ # save script (if necessary)
848
+ if options['show-source-link']:
849
+ Path(build_dir, output_base + source_ext).write_text(
850
+ doctest.script_from_examples(code)
851
+ if source_file_name == rst_file and is_doctest
852
+ else code,
853
+ encoding='utf-8')
854
+
855
+ # make figures
856
+ try:
857
+ results = render_figures(code=code,
858
+ code_path=source_file_name,
859
+ output_dir=build_dir,
860
+ output_base=output_base,
861
+ context=keep_context,
862
+ function_name=function_name,
863
+ config=config,
864
+ context_reset=context_opt == 'reset',
865
+ close_figs=context_opt == 'close-figs',
866
+ code_includes=source_file_includes)
867
+ errors = []
868
+ except PlotError as err:
869
+ reporter = state.memo.reporter
870
+ sm = reporter.system_message(
871
+ 2, "Exception occurred in plotting {}\n from {}:\n{}".format(
872
+ output_base, source_file_name, err),
873
+ line=lineno)
874
+ results = [(code, [])]
875
+ errors = [sm]
876
+
877
+ # Properly indent the caption
878
+ if caption and config.plot_srcset:
879
+ caption = ':caption: ' + caption.replace('\n', ' ')
880
+ elif caption:
881
+ caption = '\n' + '\n'.join(' ' + line.strip()
882
+ for line in caption.split('\n'))
883
+ # generate output restructuredtext
884
+ total_lines = []
885
+ for j, (code_piece, images) in enumerate(results):
886
+ if options['include-source']:
887
+ if is_doctest:
888
+ lines = ['', *code_piece.splitlines()]
889
+ else:
890
+ lines = ['.. code-block:: python', '',
891
+ *textwrap.indent(code_piece, ' ').splitlines()]
892
+ source_code = "\n".join(lines)
893
+ else:
894
+ source_code = ""
895
+
896
+ if nofigs:
897
+ images = []
898
+
899
+ if 'alt' in options:
900
+ options['alt'] = options['alt'].replace('\n', ' ')
901
+
902
+ opts = [
903
+ f':{key}: {val}' for key, val in options.items()
904
+ if key in ('alt', 'height', 'width', 'scale', 'align', 'class')]
905
+
906
+ # Not-None src_name signals the need for a source download in the
907
+ # generated html
908
+ if j == 0 and options['show-source-link']:
909
+ src_name = output_base + source_ext
910
+ else:
911
+ src_name = None
912
+ if config.plot_srcset:
913
+ srcset = [*_parse_srcset(config.plot_srcset).values()]
914
+ template = TEMPLATE_SRCSET
915
+ else:
916
+ srcset = None
917
+ template = TEMPLATE
918
+
919
+ result = jinja2.Template(config.plot_template or template).render(
920
+ default_fmt=default_fmt,
921
+ build_dir=build_dir_link,
922
+ src_name=src_name,
923
+ multi_image=len(images) > 1,
924
+ options=opts,
925
+ srcset=srcset,
926
+ images=images,
927
+ source_code=source_code,
928
+ html_show_formats=config.plot_html_show_formats and len(images),
929
+ caption=caption)
930
+ total_lines.extend(result.split("\n"))
931
+ total_lines.extend("\n")
932
+
933
+ if total_lines:
934
+ state_machine.insert_input(total_lines, source=source_file_name)
935
+
936
+ return errors
lib/python3.12/site-packages/matplotlib/sphinxext/roles.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Custom roles for the Matplotlib documentation.
3
+
4
+ .. warning::
5
+
6
+ These roles are considered semi-public. They are only intended to be used in
7
+ the Matplotlib documentation.
8
+
9
+ However, it can happen that downstream packages end up pulling these roles into
10
+ their documentation, which will result in documentation build errors. The following
11
+ describes the exact mechanism and how to fix the errors.
12
+
13
+ There are two ways, Matplotlib docstrings can end up in downstream documentation.
14
+ You have to subclass a Matplotlib class and either use the ``:inherited-members:``
15
+ option in your autodoc configuration, or you have to override a method without
16
+ specifying a new docstring; the new method will inherit the original docstring and
17
+ still render in your autodoc. If the docstring contains one of the custom sphinx
18
+ roles, you'll see one of the following error messages:
19
+
20
+ .. code-block:: none
21
+
22
+ Unknown interpreted text role "mpltype".
23
+ Unknown interpreted text role "rc".
24
+
25
+ To fix this, you can add this module as extension to your sphinx :file:`conf.py`::
26
+
27
+ extensions = [
28
+ 'matplotlib.sphinxext.roles',
29
+ # Other extensions.
30
+ ]
31
+
32
+ .. warning::
33
+
34
+ Direct use of these roles in other packages is not officially supported. We
35
+ reserve the right to modify or remove these roles without prior notification.
36
+ """
37
+
38
+ from urllib.parse import urlsplit, urlunsplit
39
+
40
+ from docutils import nodes
41
+
42
+ import matplotlib
43
+ from matplotlib import rcParamsDefault
44
+
45
+
46
+ class _QueryReference(nodes.Inline, nodes.TextElement):
47
+ """
48
+ Wraps a reference or pending reference to add a query string.
49
+
50
+ The query string is generated from the attributes added to this node.
51
+
52
+ Also equivalent to a `~docutils.nodes.literal` node.
53
+ """
54
+
55
+ def to_query_string(self):
56
+ """Generate query string from node attributes."""
57
+ return '&'.join(f'{name}={value}' for name, value in self.attlist())
58
+
59
+
60
+ def _visit_query_reference_node(self, node):
61
+ """
62
+ Resolve *node* into query strings on its ``reference`` children.
63
+
64
+ Then act as if this is a `~docutils.nodes.literal`.
65
+ """
66
+ query = node.to_query_string()
67
+ for refnode in node.findall(nodes.reference):
68
+ uri = urlsplit(refnode['refuri'])._replace(query=query)
69
+ refnode['refuri'] = urlunsplit(uri)
70
+
71
+ self.visit_literal(node)
72
+
73
+
74
+ def _depart_query_reference_node(self, node):
75
+ """
76
+ Act as if this is a `~docutils.nodes.literal`.
77
+ """
78
+ self.depart_literal(node)
79
+
80
+
81
+ def _rcparam_role(name, rawtext, text, lineno, inliner, options=None, content=None):
82
+ """
83
+ Sphinx role ``:rc:`` to highlight and link ``rcParams`` entries.
84
+
85
+ Usage: Give the desired ``rcParams`` key as parameter.
86
+
87
+ :code:`:rc:`figure.dpi`` will render as: :rc:`figure.dpi`
88
+ """
89
+ # Generate a pending cross-reference so that Sphinx will ensure this link
90
+ # isn't broken at some point in the future.
91
+ title = f'rcParams["{text}"]'
92
+ target = 'matplotlibrc-sample'
93
+ ref_nodes, messages = inliner.interpreted(title, f'{title} <{target}>',
94
+ 'ref', lineno)
95
+
96
+ qr = _QueryReference(rawtext, highlight=text)
97
+ qr += ref_nodes
98
+ node_list = [qr]
99
+
100
+ # The default backend would be printed as "agg", but that's not correct (as
101
+ # the default is actually determined by fallback).
102
+ if text in rcParamsDefault and text != "backend":
103
+ node_list.extend([
104
+ nodes.Text(' (default: '),
105
+ nodes.literal('', repr(rcParamsDefault[text])),
106
+ nodes.Text(')'),
107
+ ])
108
+
109
+ return node_list, messages
110
+
111
+
112
+ def _mpltype_role(name, rawtext, text, lineno, inliner, options=None, content=None):
113
+ """
114
+ Sphinx role ``:mpltype:`` for custom matplotlib types.
115
+
116
+ In Matplotlib, there are a number of type-like concepts that do not have a
117
+ direct type representation; example: color. This role allows to properly
118
+ highlight them in the docs and link to their definition.
119
+
120
+ Currently supported values:
121
+
122
+ - :code:`:mpltype:`color`` will render as: :mpltype:`color`
123
+
124
+ """
125
+ mpltype = text
126
+ type_to_link_target = {
127
+ 'color': 'colors_def',
128
+ }
129
+ if mpltype not in type_to_link_target:
130
+ raise ValueError(f"Unknown mpltype: {mpltype!r}")
131
+
132
+ node_list, messages = inliner.interpreted(
133
+ mpltype, f'{mpltype} <{type_to_link_target[mpltype]}>', 'ref', lineno)
134
+ return node_list, messages
135
+
136
+
137
+ def setup(app):
138
+ app.add_role("rc", _rcparam_role)
139
+ app.add_role("mpltype", _mpltype_role)
140
+ app.add_node(
141
+ _QueryReference,
142
+ html=(_visit_query_reference_node, _depart_query_reference_node),
143
+ latex=(_visit_query_reference_node, _depart_query_reference_node),
144
+ text=(_visit_query_reference_node, _depart_query_reference_node),
145
+ )
146
+ return {"version": matplotlib.__version__,
147
+ "parallel_read_safe": True, "parallel_write_safe": True}
lib/python3.12/site-packages/matplotlib/tests/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (600 Bytes). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/conftest.cpython-312.pyc ADDED
Binary file (392 Bytes). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_afm.cpython-312.pyc ADDED
Binary file (5.19 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_agg.cpython-312.pyc ADDED
Binary file (20.1 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_agg_filter.cpython-312.pyc ADDED
Binary file (1.53 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_animation.cpython-312.pyc ADDED
Binary file (28.4 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_api.cpython-312.pyc ADDED
Binary file (10.9 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_arrow_patches.cpython-312.pyc ADDED
Binary file (9.23 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_artist.cpython-312.pyc ADDED
Binary file (30.6 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_axis.cpython-312.pyc ADDED
Binary file (2.48 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_bases.cpython-312.pyc ADDED
Binary file (35.3 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_cairo.cpython-312.pyc ADDED
Binary file (2.54 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_gtk3.cpython-312.pyc ADDED
Binary file (4.74 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_inline.cpython-312.pyc ADDED
Binary file (2.56 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_macosx.cpython-312.pyc ADDED
Binary file (4.21 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_nbagg.cpython-312.pyc ADDED
Binary file (2.24 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_pdf.cpython-312.pyc ADDED
Binary file (26.2 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_pgf.cpython-312.pyc ADDED
Binary file (21.4 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_ps.cpython-312.pyc ADDED
Binary file (21.3 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_qt.cpython-312.pyc ADDED
Binary file (19.4 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_registry.cpython-312.pyc ADDED
Binary file (8.66 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_svg.cpython-312.pyc ADDED
Binary file (38 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_template.cpython-312.pyc ADDED
Binary file (3.78 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_tk.cpython-312.pyc ADDED
Binary file (13.8 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_tools.cpython-312.pyc ADDED
Binary file (853 Bytes). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backend_webagg.cpython-312.pyc ADDED
Binary file (1.77 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_backends_interactive.cpython-312.pyc ADDED
Binary file (39.2 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_basic.cpython-312.pyc ADDED
Binary file (1.82 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_bbox_tight.cpython-312.pyc ADDED
Binary file (10.1 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_bezier.cpython-312.pyc ADDED
Binary file (680 Bytes). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_category.cpython-312.pyc ADDED
Binary file (24 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_cbook.cpython-312.pyc ADDED
Binary file (58.9 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_collections.cpython-312.pyc ADDED
Binary file (80.5 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_colorbar.cpython-312.pyc ADDED
Binary file (74.1 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_colors.cpython-312.pyc ADDED
Binary file (95.7 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_compare_images.cpython-312.pyc ADDED
Binary file (2.16 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_constrainedlayout.cpython-312.pyc ADDED
Binary file (41.3 kB). View file
 
lib/python3.12/site-packages/matplotlib/tests/__pycache__/test_container.cpython-312.pyc ADDED
Binary file (1.77 kB). View file