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.
Files changed (65) hide show
  1. fluxplot/__init__.py +115 -0
  2. fluxplot/_fieldmap.py +97 -0
  3. fluxplot/_mesh_reduce.py +54 -0
  4. fluxplot/_scene3d_size.py +95 -0
  5. fluxplot/_viewer/THIRD-PARTY.txt +23 -0
  6. fluxplot/_viewer/flux-model3d-viewer.min.js +4221 -0
  7. fluxplot/_viewer/stamp.json +4 -0
  8. fluxplot/api.py +1196 -0
  9. fluxplot/autotag.py +164 -0
  10. fluxplot/base.mplstyle +0 -0
  11. fluxplot/brackets.py +242 -0
  12. fluxplot/canonical_json.py +23 -0
  13. fluxplot/capture.py +150 -0
  14. fluxplot/colorcheck.py +285 -0
  15. fluxplot/colors.py +727 -0
  16. fluxplot/colorscale.py +477 -0
  17. fluxplot/data.py +178 -0
  18. fluxplot/definitions/colormaps.json +1639 -0
  19. fluxplot/definitions/flexoki.tokens.json +2571 -0
  20. fluxplot/definitions/palettes.json +2547 -0
  21. fluxplot/descriptors.py +87 -0
  22. fluxplot/fields.py +611 -0
  23. fluxplot/fits.py +240 -0
  24. fluxplot/glb.py +84 -0
  25. fluxplot/ids.py +173 -0
  26. fluxplot/images.py +362 -0
  27. fluxplot/integrity.py +27 -0
  28. fluxplot/manifest.py +788 -0
  29. fluxplot/mesh3d.py +376 -0
  30. fluxplot/panels.py +284 -0
  31. fluxplot/postprocess.py +638 -0
  32. fluxplot/presets.py +66 -0
  33. fluxplot/provenance.py +177 -0
  34. fluxplot/raster.py +295 -0
  35. fluxplot/recipe.py +178 -0
  36. fluxplot/render.py +66 -0
  37. fluxplot/roles.py +147 -0
  38. fluxplot/scene3d.py +386 -0
  39. fluxplot/scene3d_manifest.py +112 -0
  40. fluxplot/scene3d_viewer.py +633 -0
  41. fluxplot/schemas/.gitkeep +0 -0
  42. fluxplot/schemas/manifest.schema.json +2479 -0
  43. fluxplot/schemas/recipe.schema.json +179 -0
  44. fluxplot/schemas/scene3d.schema.json +461 -0
  45. fluxplot/seaborn_adapters.py +323 -0
  46. fluxplot/signature_fluxplots/__init__.py +18 -0
  47. fluxplot/signature_fluxplots/_colour.py +412 -0
  48. fluxplot/signature_fluxplots/fluxbox.py +433 -0
  49. fluxplot/signature_fluxplots/glowbar.py +769 -0
  50. fluxplot/signature_fluxplots/hexmatrix.py +927 -0
  51. fluxplot/stats/__init__.py +63 -0
  52. fluxplot/stats/_common.py +196 -0
  53. fluxplot/stats/multi_group.py +443 -0
  54. fluxplot/stats/paired.py +209 -0
  55. fluxplot/stats/two_group.py +149 -0
  56. fluxplot/style.py +469 -0
  57. fluxplot/surface.py +487 -0
  58. fluxplot/surface3d.py +197 -0
  59. fluxplot/tagger.py +561 -0
  60. fluxplot/version.py +19 -0
  61. fluxplot-0.1.0.dist-info/METADATA +1199 -0
  62. fluxplot-0.1.0.dist-info/RECORD +65 -0
  63. fluxplot-0.1.0.dist-info/WHEEL +4 -0
  64. fluxplot-0.1.0.dist-info/licenses/LICENSE +21 -0
  65. fluxplot-0.1.0.dist-info/licenses/THIRD_PARTY_NOTICES.md +472 -0
@@ -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