gsplot 0.4.0__tar.gz → 0.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gsplot-0.4.0 → gsplot-0.4.2}/PKG-INFO +1 -1
- {gsplot-0.4.0 → gsplot-0.4.2}/pyproject.toml +1 -1
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/__init__.py +6 -2
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/__init__.pyi +6 -2
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy_api.py +56 -20
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/root.py +1 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/root_api.py +98 -85
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_core/plans.py +4 -3
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_core/targets.py +4 -3
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_core/types.py +100 -15
- gsplot-0.4.2/src/gsplot/_figure/fit.py +365 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_figure/layout.py +42 -16
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_figure/output.py +34 -11
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_plot/basic.py +2 -2
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_plot/colored.py +34 -4
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_plot/series.py +4 -4
- gsplot-0.4.2/src/gsplot/_style/axes.py +1404 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_style/legends.py +452 -100
- gsplot-0.4.2/src/gsplot/_style/panels.py +673 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_style/paper.py +3 -1
- gsplot-0.4.0/src/gsplot/_style/axes.py +0 -793
- gsplot-0.4.0/src/gsplot/_style/panels.py +0 -373
- {gsplot-0.4.0 → gsplot-0.4.2}/LICENSE +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/README.md +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/config.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/base/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/base/base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/base/base_alias_validator.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/color/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/color/colormap.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/config/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/config/config.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/data/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/data/load_file.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/figure/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/figure/axes.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/figure/axes_base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/figure/axes_inset.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/figure/axes_range_base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/figure/figure_tools.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/figure/show.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/figure/store.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/hello_world/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/hello_world/hello_world.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/logger.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/path/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/path/path.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/plot/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/plot/line.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/plot/line_base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/plot/line_colormap_base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/plot/line_colormap_dashed.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/plot/line_colormap_solid.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/plot/scatter.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/plot/scatter_colormap.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/style/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/style/graph.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/style/label.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/style/legend.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/style/legend_colormap.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/style/ticks.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/legacy/style/title.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/root_legacy.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_compat/shim.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_config/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_config/loader.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_config/model.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_config/schema.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_core/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_core/errors.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_core/numerics.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_core/options.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_core/validation.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_figure/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_figure/backend.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_figure/inset.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_io/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_io/arrays.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_io/build.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_io/metadata.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_io/paths.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_plot/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_plot/colormap.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_style/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/_style/themes.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/base/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/base/base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/base/base_alias_validator.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/color/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/color/colormap.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/config/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/config/config.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/data/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/data/load_file.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/figure/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/figure/axes.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/figure/axes_base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/figure/axes_inset.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/figure/axes_range_base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/figure/figure_tools.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/figure/show.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/figure/store.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/hello_world/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/hello_world/hello_world.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/logger.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/path/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/path/path.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/plot/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/plot/line.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/plot/line_base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/plot/line_colormap_base.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/plot/line_colormap_dashed.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/plot/line_colormap_solid.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/plot/scatter.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/plot/scatter_colormap.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/py.typed +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/style/__init__.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/style/graph.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/style/label.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/style/legend.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/style/legend_colormap.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/style/ticks.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/style/title.py +0 -0
- {gsplot-0.4.0 → gsplot-0.4.2}/src/gsplot/version.py +0 -0
|
@@ -7,7 +7,7 @@ configuration, logging, metadata-file, or backend initialization.
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
-
from typing import TYPE_CHECKING, Any
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Callable
|
|
11
11
|
|
|
12
12
|
from ._compat.root import canonical_names as _canonical_names
|
|
13
13
|
from ._compat.root import legacy_names as _legacy_names
|
|
@@ -20,6 +20,8 @@ if TYPE_CHECKING:
|
|
|
20
20
|
# Runtime lookup stays lazy. Static analyzers see the canonical source
|
|
21
21
|
# objects instead of an ``Any``-typed dynamic facade, so the shipped
|
|
22
22
|
# ``py.typed`` marker provides useful signatures to downstream callers.
|
|
23
|
+
from matplotlib.legend import Legend as _Legend
|
|
24
|
+
|
|
23
25
|
from ._compat.config import load_config
|
|
24
26
|
from ._config.model import Config
|
|
25
27
|
from ._core.errors import (
|
|
@@ -75,6 +77,7 @@ if TYPE_CHECKING:
|
|
|
75
77
|
square,
|
|
76
78
|
style_axes,
|
|
77
79
|
suptitle,
|
|
80
|
+
ticks,
|
|
78
81
|
title,
|
|
79
82
|
)
|
|
80
83
|
from ._style.legends import cmap_legend, legend, legend_entries, legends
|
|
@@ -114,7 +117,7 @@ if TYPE_CHECKING:
|
|
|
114
117
|
legend_handlers: Any
|
|
115
118
|
legend_reverse: Any
|
|
116
119
|
legend_get_handlers: Any
|
|
117
|
-
legend_colormap:
|
|
120
|
+
legend_colormap: Callable[..., _Legend]
|
|
118
121
|
ticks_off: Any
|
|
119
122
|
ticks_on: Any
|
|
120
123
|
ticks_on_axes: Any
|
|
@@ -139,6 +142,7 @@ __all__ = [
|
|
|
139
142
|
"title",
|
|
140
143
|
"suptitle",
|
|
141
144
|
"minor_ticks",
|
|
145
|
+
"ticks",
|
|
142
146
|
"box_aspect",
|
|
143
147
|
"panel_labels",
|
|
144
148
|
"index",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
|
|
5
|
+
from matplotlib.legend import Legend as _Legend
|
|
4
6
|
|
|
5
7
|
from ._compat.config import load_config as load_config
|
|
6
8
|
from ._config.model import Config as Config
|
|
@@ -60,6 +62,7 @@ from ._style.axes import minor_ticks as minor_ticks
|
|
|
60
62
|
from ._style.axes import square as square
|
|
61
63
|
from ._style.axes import style_axes as style_axes
|
|
62
64
|
from ._style.axes import suptitle as suptitle
|
|
65
|
+
from ._style.axes import ticks as ticks
|
|
63
66
|
from ._style.axes import title as title
|
|
64
67
|
from ._style.legends import cmap_legend as cmap_legend
|
|
65
68
|
from ._style.legends import legend as legend
|
|
@@ -104,7 +107,7 @@ legend_axes: Any
|
|
|
104
107
|
legend_handlers: Any
|
|
105
108
|
legend_reverse: Any
|
|
106
109
|
legend_get_handlers: Any
|
|
107
|
-
legend_colormap:
|
|
110
|
+
legend_colormap: Callable[..., _Legend]
|
|
108
111
|
ticks_off: Any
|
|
109
112
|
ticks_on: Any
|
|
110
113
|
ticks_on_axes: Any
|
|
@@ -129,6 +132,7 @@ __all__ = [
|
|
|
129
132
|
"title",
|
|
130
133
|
"suptitle",
|
|
131
134
|
"minor_ticks",
|
|
135
|
+
"ticks",
|
|
132
136
|
"box_aspect",
|
|
133
137
|
"panel_labels",
|
|
134
138
|
"index",
|
|
@@ -20,7 +20,9 @@ from typing import Any, Literal, cast
|
|
|
20
20
|
import numpy as np
|
|
21
21
|
from matplotlib import ticker
|
|
22
22
|
from matplotlib.axes import Axes
|
|
23
|
+
from matplotlib.axes._base import _AxesBase
|
|
23
24
|
from matplotlib.figure import Figure
|
|
25
|
+
from matplotlib.legend import Legend
|
|
24
26
|
from mpl_toolkits.axes_grid1.inset_locator import inset_axes as _mpl_inset_axes
|
|
25
27
|
from numpy.typing import ArrayLike, NDArray
|
|
26
28
|
|
|
@@ -41,7 +43,7 @@ from .._style.axes import box_aspect as _box_aspect
|
|
|
41
43
|
from .._style.axes import minor_ticks as _minor_ticks
|
|
42
44
|
from .._style.axes import style_axes as _style_axes
|
|
43
45
|
from .._style.axes import title as _title
|
|
44
|
-
from .._style.legends import
|
|
46
|
+
from .._style.legends import _create_cmap_legend, _legacy_colormap_values
|
|
45
47
|
from .._style.legends import legend as _legend
|
|
46
48
|
from .._style.legends import legend_entries as _legend_entries
|
|
47
49
|
from .._style.legends import legends as _legends
|
|
@@ -310,16 +312,21 @@ def _legacy_limits(
|
|
|
310
312
|
if value is None:
|
|
311
313
|
return None, "linear", None, None
|
|
312
314
|
if isinstance(value, (str, bytes)):
|
|
315
|
+
if value in ("", "*"):
|
|
316
|
+
return None, "linear", None, None
|
|
313
317
|
raise LayoutError("legacy limits must be a finite sequence")
|
|
314
318
|
values = tuple(value)
|
|
315
319
|
if len(values) < 2:
|
|
316
320
|
raise LayoutError("legacy limits must contain two values")
|
|
317
|
-
|
|
318
|
-
limits =
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
321
|
+
if values[0] in (None, "", "*") and values[1] in (None, "", "*"):
|
|
322
|
+
limits = None
|
|
323
|
+
else:
|
|
324
|
+
try:
|
|
325
|
+
limits = (float(cast(Any, values[0])), float(cast(Any, values[1])))
|
|
326
|
+
except (TypeError, ValueError) as exc:
|
|
327
|
+
raise LayoutError("legacy limits must contain finite values") from exc
|
|
328
|
+
if not np.all(np.isfinite(limits)) or limits[0] == limits[1]:
|
|
329
|
+
raise LayoutError("legacy limits must contain finite unequal values")
|
|
323
330
|
scale = values[2] if len(values) > 2 and isinstance(values[2], str) else "linear"
|
|
324
331
|
if scale not in {"linear", "log", "symlog", "logit"}:
|
|
325
332
|
raise LayoutError(f"unsupported legacy scale: {scale!r}")
|
|
@@ -820,40 +827,69 @@ def legend_colormap(
|
|
|
820
827
|
vmax: float = 1,
|
|
821
828
|
reverse: bool = False,
|
|
822
829
|
**props: Any,
|
|
823
|
-
) ->
|
|
824
|
-
"""
|
|
830
|
+
) -> Legend:
|
|
831
|
+
"""Create a v0.2-compatible horizontal gradient Legend.
|
|
832
|
+
|
|
833
|
+
Parameters
|
|
834
|
+
----------
|
|
835
|
+
ax
|
|
836
|
+
Explicit target Axes.
|
|
837
|
+
cmap
|
|
838
|
+
Non-empty registered Matplotlib colormap name.
|
|
839
|
+
label
|
|
840
|
+
Optional gradient label. ``None`` returns an empty Legend.
|
|
841
|
+
num_stripes
|
|
842
|
+
Positive requested stripe count; values above 256 are clamped.
|
|
843
|
+
vmin, vmax
|
|
844
|
+
Finite raw values passed directly to the colormap through
|
|
845
|
+
``linspace(vmin, vmax, N_effective)``. Equal and descending bounds are
|
|
846
|
+
valid and retain their sampled order.
|
|
847
|
+
reverse
|
|
848
|
+
Reverse the final sampled RGBA sequence from left to right.
|
|
849
|
+
**props
|
|
850
|
+
Finite Matplotlib Legend properties. If omitted, Matplotlib's
|
|
851
|
+
call-time rcParams provide the defaults.
|
|
852
|
+
|
|
853
|
+
Notes
|
|
854
|
+
-----
|
|
855
|
+
This deprecated adapter always replaces an existing Legend because the
|
|
856
|
+
historical function has no ``replace`` keyword. Its rendering helper is
|
|
857
|
+
shared with :func:`gsplot.cmap_legend`, but its raw ``vmin``/``vmax``
|
|
858
|
+
sampling is deliberately not translated to canonical ``norm`` semantics.
|
|
859
|
+
"""
|
|
825
860
|
|
|
826
861
|
_warn("legend_colormap", "cmap_legend")
|
|
827
|
-
|
|
862
|
+
colors = _legacy_colormap_values(cmap, num_stripes, vmin, vmax, reverse)
|
|
863
|
+
return _create_cmap_legend(
|
|
828
864
|
ax,
|
|
829
|
-
|
|
830
|
-
label
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
865
|
+
colors,
|
|
866
|
+
label,
|
|
867
|
+
replace=True,
|
|
868
|
+
props=None,
|
|
869
|
+
kwargs=props,
|
|
870
|
+
ambient=True,
|
|
835
871
|
)
|
|
836
872
|
|
|
837
873
|
|
|
838
|
-
def ticks_off(ax: Axes, mode: str = "xy") -> None:
|
|
874
|
+
def ticks_off(ax: Axes | _AxesBase, mode: str = "xy") -> None:
|
|
839
875
|
"""Adapt legacy minor-tick disabling to the canonical selector."""
|
|
840
876
|
|
|
841
877
|
_warn("ticks_off", "minor_ticks")
|
|
842
878
|
selected = {"xy": "both"}.get(mode, mode)
|
|
843
879
|
_minor_ticks(
|
|
844
|
-
ax,
|
|
880
|
+
cast(Any, ax),
|
|
845
881
|
False,
|
|
846
882
|
axis=cast(Literal["x", "y", "both"], selected),
|
|
847
883
|
)
|
|
848
884
|
|
|
849
885
|
|
|
850
|
-
def ticks_on(ax: Axes, mode: str = "xy") -> None:
|
|
886
|
+
def ticks_on(ax: Axes | _AxesBase, mode: str = "xy") -> None:
|
|
851
887
|
"""Adapt legacy minor-tick enabling to the canonical selector."""
|
|
852
888
|
|
|
853
889
|
_warn("ticks_on", "minor_ticks")
|
|
854
890
|
selected = {"xy": "both"}.get(mode, mode)
|
|
855
891
|
_minor_ticks(
|
|
856
|
-
ax,
|
|
892
|
+
cast(Any, ax),
|
|
857
893
|
True,
|
|
858
894
|
axis=cast(Literal["x", "y", "both"], selected),
|
|
859
895
|
)
|
|
@@ -86,6 +86,7 @@ _CANONICAL_EXPORTS: Final[dict[str, tuple[str, str]]] = {
|
|
|
86
86
|
"title": ("gsplot._compat.root_api", "title"),
|
|
87
87
|
"suptitle": ("gsplot._style.axes", "suptitle"),
|
|
88
88
|
"minor_ticks": ("gsplot._style.axes", "minor_ticks"),
|
|
89
|
+
"ticks": ("gsplot._style.axes", "ticks"),
|
|
89
90
|
"box_aspect": ("gsplot._style.axes", "box_aspect"),
|
|
90
91
|
"panel_labels": ("gsplot._style.panels", "panel_labels"),
|
|
91
92
|
"index": ("gsplot._style.panels", "index"),
|
|
@@ -15,6 +15,7 @@ from typing import Any, get_type_hints
|
|
|
15
15
|
from weakref import WeakKeyDictionary
|
|
16
16
|
|
|
17
17
|
from matplotlib.axes import Axes
|
|
18
|
+
from matplotlib.axes._base import _AxesBase
|
|
18
19
|
from matplotlib.figure import Figure
|
|
19
20
|
from numpy.typing import ArrayLike
|
|
20
21
|
|
|
@@ -32,7 +33,7 @@ from .._style.legends import legend as _legend
|
|
|
32
33
|
from .._style.paper import PAPER_CYCLE_RGBA as _LEGACY_COLORS
|
|
33
34
|
|
|
34
35
|
_UNSET = object()
|
|
35
|
-
_LEGACY_PLOT_COUNTS: WeakKeyDictionary[Axes, int] = WeakKeyDictionary()
|
|
36
|
+
_LEGACY_PLOT_COUNTS: WeakKeyDictionary[Axes | _AxesBase, int] = WeakKeyDictionary()
|
|
36
37
|
|
|
37
38
|
_LEGACY_LEGEND_KEYS = {
|
|
38
39
|
"handlers",
|
|
@@ -389,7 +390,7 @@ def scatter(
|
|
|
389
390
|
def _legacy_label_records(value: Any) -> tuple[Any, ...] | None:
|
|
390
391
|
"""Recognize non-empty historical records without reading pyplot state."""
|
|
391
392
|
|
|
392
|
-
if isinstance(value, (str, bytes, Mapping, Axes)):
|
|
393
|
+
if isinstance(value, (str, bytes, Mapping, Axes, _AxesBase)):
|
|
393
394
|
return None
|
|
394
395
|
try:
|
|
395
396
|
records = tuple(value)
|
|
@@ -430,6 +431,14 @@ def label(
|
|
|
430
431
|
pad: Any = _UNSET,
|
|
431
432
|
xpad: Any = _UNSET,
|
|
432
433
|
ypad: Any = _UNSET,
|
|
434
|
+
margin: Any = _UNSET,
|
|
435
|
+
xmargin: Any = _UNSET,
|
|
436
|
+
ymargin: Any = _UNSET,
|
|
437
|
+
top: Any = _UNSET,
|
|
438
|
+
bottom: Any = _UNSET,
|
|
439
|
+
left: Any = _UNSET,
|
|
440
|
+
right: Any = _UNSET,
|
|
441
|
+
direction: Any = _UNSET,
|
|
433
442
|
square: Any = _UNSET,
|
|
434
443
|
index: Any = _UNSET,
|
|
435
444
|
lab_lims: Any = _UNSET,
|
|
@@ -464,6 +473,7 @@ def label(
|
|
|
464
473
|
fontdict: Any = _UNSET,
|
|
465
474
|
labelpad: Any = _UNSET,
|
|
466
475
|
loc: Any = _UNSET,
|
|
476
|
+
props: Any = _UNSET,
|
|
467
477
|
) -> Any:
|
|
468
478
|
"""Dispatch explicit concise labels or historical current-Figure records."""
|
|
469
479
|
|
|
@@ -479,6 +489,34 @@ def label(
|
|
|
479
489
|
records = _legacy_label_records(target)
|
|
480
490
|
else:
|
|
481
491
|
records = None
|
|
492
|
+
text_props = {
|
|
493
|
+
name: value
|
|
494
|
+
for name, value in (
|
|
495
|
+
("alpha", alpha),
|
|
496
|
+
("color", color),
|
|
497
|
+
("fontfamily", fontfamily),
|
|
498
|
+
("fontproperties", fontproperties),
|
|
499
|
+
("fontsize", fontsize),
|
|
500
|
+
("fontstretch", fontstretch),
|
|
501
|
+
("fontstyle", fontstyle),
|
|
502
|
+
("fontvariant", fontvariant),
|
|
503
|
+
("fontweight", fontweight),
|
|
504
|
+
("ha", ha),
|
|
505
|
+
("horizontalalignment", horizontalalignment),
|
|
506
|
+
("label", label),
|
|
507
|
+
("linespacing", linespacing),
|
|
508
|
+
("math_fontfamily", math_fontfamily),
|
|
509
|
+
("multialignment", multialignment),
|
|
510
|
+
("parse_math", parse_math),
|
|
511
|
+
("rotation", rotation),
|
|
512
|
+
("rotation_mode", rotation_mode),
|
|
513
|
+
("va", va),
|
|
514
|
+
("verticalalignment", verticalalignment),
|
|
515
|
+
("visible", visible),
|
|
516
|
+
("zorder", zorder),
|
|
517
|
+
)
|
|
518
|
+
if value is not _UNSET
|
|
519
|
+
}
|
|
482
520
|
legacy_controls = _provided(
|
|
483
521
|
{
|
|
484
522
|
"legacy_xpad_layout": legacy_xpad_layout,
|
|
@@ -489,28 +527,6 @@ def label(
|
|
|
489
527
|
"tight_layout": tight_layout,
|
|
490
528
|
"xpad_layout": xpad_layout,
|
|
491
529
|
"ypad_layout": ypad_layout,
|
|
492
|
-
"alpha": alpha,
|
|
493
|
-
"color": color,
|
|
494
|
-
"fontfamily": fontfamily,
|
|
495
|
-
"fontproperties": fontproperties,
|
|
496
|
-
"fontsize": fontsize,
|
|
497
|
-
"fontstretch": fontstretch,
|
|
498
|
-
"fontstyle": fontstyle,
|
|
499
|
-
"fontvariant": fontvariant,
|
|
500
|
-
"fontweight": fontweight,
|
|
501
|
-
"ha": ha,
|
|
502
|
-
"horizontalalignment": horizontalalignment,
|
|
503
|
-
"label": label,
|
|
504
|
-
"linespacing": linespacing,
|
|
505
|
-
"math_fontfamily": math_fontfamily,
|
|
506
|
-
"multialignment": multialignment,
|
|
507
|
-
"parse_math": parse_math,
|
|
508
|
-
"rotation": rotation,
|
|
509
|
-
"rotation_mode": rotation_mode,
|
|
510
|
-
"va": va,
|
|
511
|
-
"verticalalignment": verticalalignment,
|
|
512
|
-
"visible": visible,
|
|
513
|
-
"zorder": zorder,
|
|
514
530
|
"fontdict": fontdict,
|
|
515
531
|
"labelpad": labelpad,
|
|
516
532
|
"loc": loc,
|
|
@@ -536,10 +552,22 @@ def label(
|
|
|
536
552
|
"pad": pad,
|
|
537
553
|
"xpad": xpad,
|
|
538
554
|
"ypad": ypad,
|
|
555
|
+
"margin": margin,
|
|
556
|
+
"xmargin": xmargin,
|
|
557
|
+
"ymargin": ymargin,
|
|
558
|
+
"top": top,
|
|
559
|
+
"bottom": bottom,
|
|
560
|
+
"left": left,
|
|
561
|
+
"right": right,
|
|
562
|
+
"direction": direction,
|
|
539
563
|
"square": square,
|
|
540
564
|
"index": index,
|
|
541
565
|
}
|
|
542
566
|
)
|
|
567
|
+
if props is not _UNSET:
|
|
568
|
+
canonical["props"] = props
|
|
569
|
+
elif text_props:
|
|
570
|
+
canonical["props"] = text_props
|
|
543
571
|
return _label(target, **canonical)
|
|
544
572
|
|
|
545
573
|
if records is None:
|
|
@@ -559,6 +587,14 @@ def label(
|
|
|
559
587
|
"pad": pad,
|
|
560
588
|
"xpad": xpad,
|
|
561
589
|
"ypad": ypad,
|
|
590
|
+
"margin": margin,
|
|
591
|
+
"xmargin": xmargin,
|
|
592
|
+
"ymargin": ymargin,
|
|
593
|
+
"top": top,
|
|
594
|
+
"bottom": bottom,
|
|
595
|
+
"left": left,
|
|
596
|
+
"right": right,
|
|
597
|
+
"direction": direction,
|
|
562
598
|
"square": square,
|
|
563
599
|
"index": index,
|
|
564
600
|
}
|
|
@@ -677,11 +713,41 @@ def legend(
|
|
|
677
713
|
) -> Any:
|
|
678
714
|
"""Dispatch canonical ``legend`` or finite legacy options."""
|
|
679
715
|
|
|
680
|
-
|
|
716
|
+
is_legacy = (
|
|
717
|
+
legacy_handles is not _UNSET
|
|
718
|
+
or legacy_labels is not _UNSET
|
|
719
|
+
or handlers is not _UNSET
|
|
720
|
+
or ncol is not _UNSET
|
|
721
|
+
)
|
|
722
|
+
if is_legacy:
|
|
723
|
+
if (legacy_handles is not _UNSET or legacy_labels is not _UNSET) and (
|
|
724
|
+
handles is not None or labels is not None
|
|
725
|
+
):
|
|
726
|
+
raise OptionError("legend cannot combine positional and canonical entries")
|
|
727
|
+
if handlers is not _UNSET:
|
|
728
|
+
if handler_map is not None:
|
|
729
|
+
raise OptionError("legend cannot combine handlers and handler_map")
|
|
730
|
+
handler_map = handlers
|
|
731
|
+
if ncol is not _UNSET:
|
|
732
|
+
if ncols is not _UNSET:
|
|
733
|
+
raise OptionError(
|
|
734
|
+
"legend: props cannot contain both 'ncol' and 'ncols'"
|
|
735
|
+
)
|
|
736
|
+
ncols = ncol
|
|
737
|
+
if legacy_handles is not _UNSET:
|
|
738
|
+
handles = legacy_handles
|
|
739
|
+
if legacy_labels is not _UNSET:
|
|
740
|
+
labels = legacy_labels
|
|
741
|
+
_warn("legend")
|
|
742
|
+
|
|
743
|
+
direct = _provided(
|
|
681
744
|
{
|
|
682
|
-
"
|
|
745
|
+
"loc": loc,
|
|
746
|
+
"frameon": frameon,
|
|
747
|
+
"fancybox": fancybox,
|
|
748
|
+
"labelspacing": labelspacing,
|
|
749
|
+
"handlelength": handlelength,
|
|
683
750
|
"ncols": ncols,
|
|
684
|
-
"ncol": ncol,
|
|
685
751
|
"fontsize": fontsize,
|
|
686
752
|
"title": title,
|
|
687
753
|
"title_fontsize": title_fontsize,
|
|
@@ -702,59 +768,6 @@ def legend(
|
|
|
702
768
|
"labelcolor": labelcolor,
|
|
703
769
|
}
|
|
704
770
|
)
|
|
705
|
-
if legacy_handles is not _UNSET:
|
|
706
|
-
legacy["_legacy_handles"] = legacy_handles
|
|
707
|
-
if legacy_labels is not _UNSET:
|
|
708
|
-
legacy["_legacy_labels"] = legacy_labels
|
|
709
|
-
if (legacy_handles is not _UNSET or legacy_labels is not _UNSET) and (
|
|
710
|
-
handles is not None or labels is not None
|
|
711
|
-
):
|
|
712
|
-
raise OptionError("legend cannot combine positional and canonical entries")
|
|
713
|
-
if legacy and props is not None:
|
|
714
|
-
raise OptionError(
|
|
715
|
-
"gsplot.legend cannot combine canonical props with legacy options"
|
|
716
|
-
)
|
|
717
|
-
direct = _provided(
|
|
718
|
-
{
|
|
719
|
-
"loc": loc,
|
|
720
|
-
"frameon": frameon,
|
|
721
|
-
"fancybox": fancybox,
|
|
722
|
-
"labelspacing": labelspacing,
|
|
723
|
-
"handlelength": handlelength,
|
|
724
|
-
}
|
|
725
|
-
)
|
|
726
|
-
if not legacy:
|
|
727
|
-
return _legend(
|
|
728
|
-
target,
|
|
729
|
-
handles=handles,
|
|
730
|
-
labels=labels,
|
|
731
|
-
handler_map=handler_map,
|
|
732
|
-
reverse=reverse,
|
|
733
|
-
replace=replace,
|
|
734
|
-
props=props,
|
|
735
|
-
**direct,
|
|
736
|
-
)
|
|
737
|
-
positional_handles = legacy.pop("_legacy_handles", _UNSET)
|
|
738
|
-
positional_labels = legacy.pop("_legacy_labels", _UNSET)
|
|
739
|
-
if handlers is not _UNSET:
|
|
740
|
-
if handler_map is not None:
|
|
741
|
-
raise OptionError("legend cannot combine handlers and handler_map")
|
|
742
|
-
handler_map = handlers
|
|
743
|
-
legacy.pop("handlers", None)
|
|
744
|
-
translated = _translate_props(
|
|
745
|
-
"legend",
|
|
746
|
-
legacy,
|
|
747
|
-
{"ncol": "ncols"},
|
|
748
|
-
)
|
|
749
|
-
if positional_handles is not _UNSET:
|
|
750
|
-
if handles is not None:
|
|
751
|
-
raise OptionError("legend received handles twice")
|
|
752
|
-
handles = positional_handles
|
|
753
|
-
if positional_labels is not _UNSET:
|
|
754
|
-
if labels is not None:
|
|
755
|
-
raise OptionError("legend received labels twice")
|
|
756
|
-
labels = positional_labels
|
|
757
|
-
_warn("legend")
|
|
758
771
|
return _legend(
|
|
759
772
|
target,
|
|
760
773
|
handles=handles,
|
|
@@ -762,7 +775,7 @@ def legend(
|
|
|
762
775
|
handler_map=handler_map,
|
|
763
776
|
reverse=reverse,
|
|
764
777
|
replace=replace,
|
|
765
|
-
props=
|
|
778
|
+
props=props,
|
|
766
779
|
**direct,
|
|
767
780
|
)
|
|
768
781
|
|
|
@@ -834,10 +847,10 @@ def title(
|
|
|
834
847
|
"y": y,
|
|
835
848
|
}
|
|
836
849
|
)
|
|
837
|
-
if isinstance(ax, Axes):
|
|
838
|
-
if text is _UNSET or title is not _UNSET
|
|
839
|
-
raise OptionError("canonical title requires text
|
|
840
|
-
return _title(ax, text, props=props)
|
|
850
|
+
if isinstance(ax, (Axes, _AxesBase)):
|
|
851
|
+
if text is _UNSET or title is not _UNSET:
|
|
852
|
+
raise OptionError("canonical title requires an explicit text value")
|
|
853
|
+
return _title(ax, text, props=props, **legacy)
|
|
841
854
|
if text is not _UNSET:
|
|
842
855
|
raise TypeError("legacy Figure title accepts one text value")
|
|
843
856
|
if title is not _UNSET:
|
|
@@ -7,6 +7,7 @@ from dataclasses import dataclass
|
|
|
7
7
|
from typing import Any, Generic, Literal, TypeVar
|
|
8
8
|
|
|
9
9
|
from matplotlib.axes import Axes
|
|
10
|
+
from matplotlib.axes._base import _AxesBase
|
|
10
11
|
from matplotlib.figure import Figure
|
|
11
12
|
|
|
12
13
|
from .errors import PlotError
|
|
@@ -24,7 +25,7 @@ def _operation_name(value: str) -> str:
|
|
|
24
25
|
return value
|
|
25
26
|
|
|
26
27
|
|
|
27
|
-
def _axis_root_figure(axis:
|
|
28
|
+
def _axis_root_figure(axis: Any) -> Figure | None:
|
|
28
29
|
"""Return an Axes root Figure without requiring ``root=True`` support."""
|
|
29
30
|
|
|
30
31
|
owner: Any = axis.get_figure()
|
|
@@ -47,7 +48,7 @@ class TargetPlan:
|
|
|
47
48
|
|
|
48
49
|
operation: str
|
|
49
50
|
figure: Figure
|
|
50
|
-
axes: tuple[Axes, ...]
|
|
51
|
+
axes: tuple[Axes | _AxesBase, ...]
|
|
51
52
|
keys: tuple[object, ...]
|
|
52
53
|
kind: TargetKind
|
|
53
54
|
|
|
@@ -61,7 +62,7 @@ class TargetPlan:
|
|
|
61
62
|
raise PlotError(f"{self.operation}: target plan is empty or incomplete")
|
|
62
63
|
if self.kind not in {"single", "sequence", "array", "mapping"}:
|
|
63
64
|
raise PlotError(f"{self.operation}: target kind is invalid")
|
|
64
|
-
if any(not isinstance(axis, Axes) for axis in self.axes):
|
|
65
|
+
if any(not isinstance(axis, (Axes, _AxesBase)) for axis in self.axes):
|
|
65
66
|
raise PlotError(f"{self.operation}: target contains a non-Axes value")
|
|
66
67
|
if len({id(axis) for axis in self.axes}) != len(self.axes):
|
|
67
68
|
raise PlotError(f"{self.operation}: target contains a duplicate Axes")
|
|
@@ -7,6 +7,7 @@ from typing import Any, TypeVar
|
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
from matplotlib.axes import Axes
|
|
10
|
+
from matplotlib.axes._base import _AxesBase
|
|
10
11
|
from matplotlib.figure import Figure
|
|
11
12
|
|
|
12
13
|
from .errors import PlotError
|
|
@@ -16,7 +17,7 @@ from .types import AxesTarget
|
|
|
16
17
|
T = TypeVar("T")
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
def _root_figure(axis: Axes, operation: str) -> Figure:
|
|
20
|
+
def _root_figure(axis: Axes | _AxesBase, operation: str) -> Figure:
|
|
20
21
|
"""Resolve an Axes root Figure without version-specific root arguments."""
|
|
21
22
|
|
|
22
23
|
owner = _axis_root_figure(axis)
|
|
@@ -30,7 +31,7 @@ def _snapshot_target(
|
|
|
30
31
|
) -> tuple[TargetKind, tuple[object, ...], tuple[Any, ...]]:
|
|
31
32
|
"""Snapshot one supported target shape without retaining its container."""
|
|
32
33
|
|
|
33
|
-
if isinstance(target, Axes):
|
|
34
|
+
if isinstance(target, (Axes, _AxesBase)):
|
|
34
35
|
return "single", (target,), (target,)
|
|
35
36
|
if isinstance(target, Mapping):
|
|
36
37
|
items = tuple(target.items())
|
|
@@ -67,7 +68,7 @@ def normalize_axes(target: AxesTarget, *, operation: str) -> TargetPlan:
|
|
|
67
68
|
kind, keys, values = _snapshot_target(target, operation)
|
|
68
69
|
if not values:
|
|
69
70
|
raise PlotError(f"{operation}: target must contain at least one Axes")
|
|
70
|
-
if any(not isinstance(value, Axes) for value in values):
|
|
71
|
+
if any(not isinstance(value, (Axes, _AxesBase)) for value in values):
|
|
71
72
|
raise PlotError(f"{operation}: target contains a non-Axes value")
|
|
72
73
|
axes = tuple(values)
|
|
73
74
|
if len({id(axis) for axis in axes}) != len(axes):
|