fluxplot 0.1.0__py3-none-any.whl
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.
- fluxplot/__init__.py +115 -0
- fluxplot/_fieldmap.py +97 -0
- fluxplot/_mesh_reduce.py +54 -0
- fluxplot/_scene3d_size.py +95 -0
- fluxplot/_viewer/THIRD-PARTY.txt +23 -0
- fluxplot/_viewer/flux-model3d-viewer.min.js +4221 -0
- fluxplot/_viewer/stamp.json +4 -0
- fluxplot/api.py +1196 -0
- fluxplot/autotag.py +164 -0
- fluxplot/base.mplstyle +0 -0
- fluxplot/brackets.py +242 -0
- fluxplot/canonical_json.py +23 -0
- fluxplot/capture.py +150 -0
- fluxplot/colorcheck.py +285 -0
- fluxplot/colors.py +727 -0
- fluxplot/colorscale.py +477 -0
- fluxplot/data.py +178 -0
- fluxplot/definitions/colormaps.json +1639 -0
- fluxplot/definitions/flexoki.tokens.json +2571 -0
- fluxplot/definitions/palettes.json +2547 -0
- fluxplot/descriptors.py +87 -0
- fluxplot/fields.py +611 -0
- fluxplot/fits.py +240 -0
- fluxplot/glb.py +84 -0
- fluxplot/ids.py +173 -0
- fluxplot/images.py +362 -0
- fluxplot/integrity.py +27 -0
- fluxplot/manifest.py +788 -0
- fluxplot/mesh3d.py +376 -0
- fluxplot/panels.py +284 -0
- fluxplot/postprocess.py +638 -0
- fluxplot/presets.py +66 -0
- fluxplot/provenance.py +177 -0
- fluxplot/raster.py +295 -0
- fluxplot/recipe.py +178 -0
- fluxplot/render.py +66 -0
- fluxplot/roles.py +147 -0
- fluxplot/scene3d.py +386 -0
- fluxplot/scene3d_manifest.py +112 -0
- fluxplot/scene3d_viewer.py +633 -0
- fluxplot/schemas/.gitkeep +0 -0
- fluxplot/schemas/manifest.schema.json +2479 -0
- fluxplot/schemas/recipe.schema.json +179 -0
- fluxplot/schemas/scene3d.schema.json +461 -0
- fluxplot/seaborn_adapters.py +323 -0
- fluxplot/signature_fluxplots/__init__.py +18 -0
- fluxplot/signature_fluxplots/_colour.py +412 -0
- fluxplot/signature_fluxplots/fluxbox.py +433 -0
- fluxplot/signature_fluxplots/glowbar.py +769 -0
- fluxplot/signature_fluxplots/hexmatrix.py +927 -0
- fluxplot/stats/__init__.py +63 -0
- fluxplot/stats/_common.py +196 -0
- fluxplot/stats/multi_group.py +443 -0
- fluxplot/stats/paired.py +209 -0
- fluxplot/stats/two_group.py +149 -0
- fluxplot/style.py +469 -0
- fluxplot/surface.py +487 -0
- fluxplot/surface3d.py +197 -0
- fluxplot/tagger.py +561 -0
- fluxplot/version.py +19 -0
- fluxplot-0.1.0.dist-info/METADATA +1199 -0
- fluxplot-0.1.0.dist-info/RECORD +65 -0
- fluxplot-0.1.0.dist-info/WHEEL +4 -0
- fluxplot-0.1.0.dist-info/licenses/LICENSE +21 -0
- fluxplot-0.1.0.dist-info/licenses/THIRD_PARTY_NOTICES.md +472 -0
fluxplot/descriptors.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Semantic descriptors — the in-memory record of "what each mark means", captured at plot time.
|
|
2
|
+
|
|
3
|
+
The registry (see ``tagger.py``) holds a list of :class:`Mark` per figure. Each Mark records the
|
|
4
|
+
meaning of one logical mark-group (a series' line, a series' points, a bar set, an overlay) plus the
|
|
5
|
+
matplotlib artist(s) that draw it, so :func:`fluxplot.save` can assign deterministic gids, capture
|
|
6
|
+
data, and emit the manifest. Geometry is never stored here — it stays authoritative in the SVG.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any, Optional, Sequence
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class Mark:
|
|
16
|
+
"""One tagged logical mark-group (a series component or a standalone overlay)."""
|
|
17
|
+
|
|
18
|
+
role: str # line | point | bar | area | errorbar | box | annotation | reference-line | ...
|
|
19
|
+
series: Optional[str] = None # source series name (None for overlays / scaffold)
|
|
20
|
+
name: Optional[str] = None # identity for overlays, e.g. annotation "peak"
|
|
21
|
+
kind: Optional[str] = None # logical series kind: line | scatter | bar | errorbar | area
|
|
22
|
+
label: Optional[str] = None # legend label, if any
|
|
23
|
+
x: Optional[Sequence[float]] = None # captured data (the user's real arrays)
|
|
24
|
+
y: Optional[Sequence[float]] = None
|
|
25
|
+
artists: list = field(default_factory=list) # mpl artist(s) this Mark draws (strong refs)
|
|
26
|
+
indexed: bool = False # True for point/bar groups → addressable per-index members
|
|
27
|
+
live_data: bool = False # refresh public artist data at save time
|
|
28
|
+
axes: Any = None # owning axes, captured before an artist can be detached
|
|
29
|
+
split_use: bool = False # True when one artist renders N <use> to split in post-process
|
|
30
|
+
data: dict = field(default_factory=dict) # extra identity (p, between, yerr, label_artist, …)
|
|
31
|
+
|
|
32
|
+
# Resolved at save() time:
|
|
33
|
+
gid: Optional[str] = None # the group/primary id
|
|
34
|
+
member_gids: list = field(default_factory=list) # per-index member ids (bars), or per-point ids
|
|
35
|
+
member_indices: list = field(default_factory=list)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class GuideTag:
|
|
40
|
+
"""A scaffold/guide element that was auto-tagged (axis, tick, label, gridline, spine, legend)."""
|
|
41
|
+
|
|
42
|
+
gid: str
|
|
43
|
+
role: str
|
|
44
|
+
axis: Optional[str] = None # "x" / "y" for axis-scoped guides
|
|
45
|
+
text: Optional[str] = None # for axis-title / tick-label text content
|
|
46
|
+
index: Optional[int] = None # per-index guides (gridline/tick/ticklabel/legend-entry)
|
|
47
|
+
series: Optional[str] = None # series this guide belongs to (legend swatch/label)
|
|
48
|
+
data: dict = field(default_factory=dict)
|
|
49
|
+
virtual: bool = False # organizational guide without one SVG wrapper
|
|
50
|
+
kind: Optional[str] = None # data-kind hint (text|line|shape|container); auto-derived from role
|
|
51
|
+
|
|
52
|
+
def __post_init__(self) -> None:
|
|
53
|
+
if self.kind is None:
|
|
54
|
+
from . import roles as _roles
|
|
55
|
+
|
|
56
|
+
self.kind = _roles.kind_for_role(self.role)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def artist_kind(artist) -> Optional[str]:
|
|
60
|
+
"""Best-effort data-kind (text | line | shape) from a matplotlib artist's class.
|
|
61
|
+
|
|
62
|
+
Used for marks whose role carries no static kind (``x-`` extension roles from
|
|
63
|
+
:func:`fluxplot.tag`, the heterogeneous ``extra`` sweep). Containers / uninferable
|
|
64
|
+
artists return ``None`` — the hint is then simply omitted (additive contract).
|
|
65
|
+
"""
|
|
66
|
+
from matplotlib.collections import Collection, LineCollection
|
|
67
|
+
from matplotlib.lines import Line2D
|
|
68
|
+
from matplotlib.patches import Patch
|
|
69
|
+
from matplotlib.text import Text
|
|
70
|
+
|
|
71
|
+
if isinstance(artist, Text):
|
|
72
|
+
return "text"
|
|
73
|
+
if isinstance(artist, (Line2D, LineCollection)):
|
|
74
|
+
return "line"
|
|
75
|
+
if isinstance(artist, (Patch, Collection)):
|
|
76
|
+
return "shape"
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def mark_kind(mark: "Mark") -> Optional[str]:
|
|
81
|
+
"""Data-kind hint for a Mark: the role's static kind, else inferred from its artist."""
|
|
82
|
+
from . import roles as _roles
|
|
83
|
+
|
|
84
|
+
k = _roles.kind_for_role(mark.role)
|
|
85
|
+
if k is not None:
|
|
86
|
+
return k
|
|
87
|
+
return artist_kind(mark.artists[0]) if mark.artists else None
|