diffract-core 0.2.1__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 (193) hide show
  1. diffract/__init__.py +52 -0
  2. diffract/configs/fast_speed_without_disk.ini +48 -0
  3. diffract/configs/hybrid.ini +74 -0
  4. diffract/configs/sqlite.ini +62 -0
  5. diffract/containers.py +405 -0
  6. diffract/core/__init__.py +23 -0
  7. diffract/core/cache/__init__.py +24 -0
  8. diffract/core/cache/containers.py +93 -0
  9. diffract/core/cache/interface.py +117 -0
  10. diffract/core/cache/redis_manager.py +464 -0
  11. diffract/core/cache/simple_manager.py +478 -0
  12. diffract/core/compute/__init__.py +46 -0
  13. diffract/core/compute/config.py +48 -0
  14. diffract/core/compute/containers.py +81 -0
  15. diffract/core/compute/decorator.py +125 -0
  16. diffract/core/compute/exceptions.py +31 -0
  17. diffract/core/compute/execution/__init__.py +14 -0
  18. diffract/core/compute/execution/_types.py +70 -0
  19. diffract/core/compute/execution/aggregation.py +74 -0
  20. diffract/core/compute/execution/aggregation_runner.py +362 -0
  21. diffract/core/compute/execution/enums.py +38 -0
  22. diffract/core/compute/execution/executor.py +125 -0
  23. diffract/core/compute/execution/parameter_runner.py +125 -0
  24. diffract/core/compute/execution/restrictions.py +61 -0
  25. diffract/core/compute/execution/strategy.py +118 -0
  26. diffract/core/compute/execution/utils.py +112 -0
  27. diffract/core/compute/extensions/__init__.py +0 -0
  28. diffract/core/compute/extensions/power_law.py +1051 -0
  29. diffract/core/compute/extensions/rmt.py +150 -0
  30. diffract/core/compute/extensions/utils.py +36 -0
  31. diffract/core/compute/field_signature.py +183 -0
  32. diffract/core/compute/kernels/__init__.py +48 -0
  33. diffract/core/compute/kernels/alignment.py +106 -0
  34. diffract/core/compute/kernels/heavy_tailed.py +394 -0
  35. diffract/core/compute/kernels/marchenko_pastur.py +99 -0
  36. diffract/core/compute/kernels/mat_decomposition.py +101 -0
  37. diffract/core/compute/kernels/mat_properties.py +53 -0
  38. diffract/core/compute/kernels/model_quality.py +27 -0
  39. diffract/core/compute/kernels/norms.py +88 -0
  40. diffract/core/compute/kernels/ranks.py +35 -0
  41. diffract/core/compute/kernels/tracy_widom.py +36 -0
  42. diffract/core/compute/metadata.py +67 -0
  43. diffract/core/compute/registry.py +485 -0
  44. diffract/core/constants.py +147 -0
  45. diffract/core/data/__init__.py +32 -0
  46. diffract/core/data/interface.py +304 -0
  47. diffract/core/data/metadata/__init__.py +15 -0
  48. diffract/core/data/metadata/containers.py +60 -0
  49. diffract/core/data/metadata/interface.py +208 -0
  50. diffract/core/data/metadata/sqlite_index.py +604 -0
  51. diffract/core/data/nn/__init__.py +43 -0
  52. diffract/core/data/nn/aggregates/__init__.py +35 -0
  53. diffract/core/data/nn/aggregates/metadata.py +96 -0
  54. diffract/core/data/nn/aggregates/proxy.py +57 -0
  55. diffract/core/data/nn/aggregates/repository.py +87 -0
  56. diffract/core/data/nn/aggregates/view.py +307 -0
  57. diffract/core/data/nn/containers.py +86 -0
  58. diffract/core/data/nn/extractors/__init__.py +49 -0
  59. diffract/core/data/nn/extractors/base.py +300 -0
  60. diffract/core/data/nn/extractors/factory.py +234 -0
  61. diffract/core/data/nn/extractors/flax.py +112 -0
  62. diffract/core/data/nn/extractors/handlers/__init__.py +39 -0
  63. diffract/core/data/nn/extractors/handlers/base.py +110 -0
  64. diffract/core/data/nn/extractors/handlers/flax_handlers.py +71 -0
  65. diffract/core/data/nn/extractors/handlers/numpy_handlers.py +63 -0
  66. diffract/core/data/nn/extractors/handlers/onnx_handlers.py +67 -0
  67. diffract/core/data/nn/extractors/handlers/tensorflow_handlers.py +82 -0
  68. diffract/core/data/nn/extractors/handlers/torch_handlers.py +124 -0
  69. diffract/core/data/nn/extractors/interface.py +56 -0
  70. diffract/core/data/nn/extractors/numpy.py +94 -0
  71. diffract/core/data/nn/extractors/onnx.py +108 -0
  72. diffract/core/data/nn/extractors/tensorflow.py +99 -0
  73. diffract/core/data/nn/extractors/torch.py +204 -0
  74. diffract/core/data/nn/params/__init__.py +27 -0
  75. diffract/core/data/nn/params/interface.py +402 -0
  76. diffract/core/data/nn/params/metadata.py +110 -0
  77. diffract/core/data/nn/params/proxy.py +93 -0
  78. diffract/core/data/nn/params/repository.py +45 -0
  79. diffract/core/data/nn/params/schema.py +82 -0
  80. diffract/core/data/nn/params/view.py +393 -0
  81. diffract/core/data/proxy.py +246 -0
  82. diffract/core/data/repository.py +227 -0
  83. diffract/core/data/utils.py +33 -0
  84. diffract/core/data/view.py +389 -0
  85. diffract/core/export/__init__.py +27 -0
  86. diffract/core/export/containers.py +47 -0
  87. diffract/core/export/exporters.py +191 -0
  88. diffract/core/export/formatters/__init__.py +23 -0
  89. diffract/core/export/formatters/base.py +68 -0
  90. diffract/core/export/formatters/dict_formatter.py +38 -0
  91. diffract/core/export/formatters/json_formatter.py +58 -0
  92. diffract/core/export/formatters/list_formatter.py +41 -0
  93. diffract/core/export/formatters/pandas_formatter.py +86 -0
  94. diffract/core/export/formatters/polars_formatter.py +86 -0
  95. diffract/core/export/formatters/registry.py +84 -0
  96. diffract/core/export/interface.py +105 -0
  97. diffract/core/parallel/__init__.py +21 -0
  98. diffract/core/parallel/containers.py +57 -0
  99. diffract/core/parallel/execution.py +91 -0
  100. diffract/core/parallel/runtime.py +91 -0
  101. diffract/core/storage/__init__.py +35 -0
  102. diffract/core/storage/base_manager.py +330 -0
  103. diffract/core/storage/containers.py +122 -0
  104. diffract/core/storage/hdf5_manager.py +856 -0
  105. diffract/core/storage/hybrid_manager.py +218 -0
  106. diffract/core/storage/interface.py +222 -0
  107. diffract/core/storage/metadata.py +89 -0
  108. diffract/core/storage/ram_manager.py +159 -0
  109. diffract/core/storage/sqlite_manager.py +1062 -0
  110. diffract/core/storage/zarr_manager.py +992 -0
  111. diffract/core/utils/__init__.py +45 -0
  112. diffract/core/utils/build.py +46 -0
  113. diffract/core/utils/exceptions.py +11 -0
  114. diffract/core/utils/hashing.py +90 -0
  115. diffract/core/utils/imports.py +292 -0
  116. diffract/core/utils/math.py +15 -0
  117. diffract/py.typed +0 -0
  118. diffract/session/__init__.py +24 -0
  119. diffract/session/errors.py +17 -0
  120. diffract/session/field_cache.py +216 -0
  121. diffract/session/namespaces/__init__.py +15 -0
  122. diffract/session/namespaces/compute/__init__.py +219 -0
  123. diffract/session/namespaces/models/__init__.py +282 -0
  124. diffract/session/namespaces/models/parameters/__init__.py +133 -0
  125. diffract/session/namespaces/models/parameters/meta_patcher.py +167 -0
  126. diffract/session/namespaces/results/__init__.py +378 -0
  127. diffract/session/namespaces/results/eraser.py +129 -0
  128. diffract/session/namespaces/results/injester.py +249 -0
  129. diffract/session/namespaces/utils/__init__.py +141 -0
  130. diffract/session/namespaces/utils/merger.py +295 -0
  131. diffract/session/namespaces/viz/__init__.py +91 -0
  132. diffract/session/namespaces/viz/_utils.py +14 -0
  133. diffract/session/namespaces/viz/box.py +207 -0
  134. diffract/session/namespaces/viz/grid.py +160 -0
  135. diffract/session/namespaces/viz/heatmap.py +164 -0
  136. diffract/session/namespaces/viz/scatter.py +202 -0
  137. diffract/session/namespaces/viz/sparkline.py +270 -0
  138. diffract/session/namespaces/viz/violin.py +212 -0
  139. diffract/session/session.py +260 -0
  140. diffract/session/utils.py +81 -0
  141. diffract/viz/__init__.py +42 -0
  142. diffract/viz/data/__init__.py +34 -0
  143. diffract/viz/data/detection.py +57 -0
  144. diffract/viz/data/extraction.py +117 -0
  145. diffract/viz/data/filtering.py +57 -0
  146. diffract/viz/data/ordering.py +129 -0
  147. diffract/viz/data/provider.py +99 -0
  148. diffract/viz/data/types.py +98 -0
  149. diffract/viz/plots/__init__.py +37 -0
  150. diffract/viz/plots/base/__init__.py +20 -0
  151. diffract/viz/plots/base/axis.py +219 -0
  152. diffract/viz/plots/base/coloraxis.py +133 -0
  153. diffract/viz/plots/base/configurator.py +18 -0
  154. diffract/viz/plots/base/jitter.py +368 -0
  155. diffract/viz/plots/base/line.py +197 -0
  156. diffract/viz/plots/base/marker.py +278 -0
  157. diffract/viz/plots/base/overlay.py +14 -0
  158. diffract/viz/plots/base/plot.py +110 -0
  159. diffract/viz/plots/base/update.py +50 -0
  160. diffract/viz/plots/boxplot.py +283 -0
  161. diffract/viz/plots/cluster.py +374 -0
  162. diffract/viz/plots/heatmap.py +168 -0
  163. diffract/viz/plots/scatter.py +233 -0
  164. diffract/viz/plots/sparkline.py +405 -0
  165. diffract/viz/plots/subplots/__init__.py +32 -0
  166. diffract/viz/plots/subplots/coloraxis.py +339 -0
  167. diffract/viz/plots/subplots/factory.py +713 -0
  168. diffract/viz/plots/subplots/grid.py +214 -0
  169. diffract/viz/plots/subplots/layout.py +370 -0
  170. diffract/viz/plots/subplots/spec.py +39 -0
  171. diffract/viz/plots/violin.py +298 -0
  172. diffract/viz/renderer.py +513 -0
  173. diffract/viz/styling/__init__.py +78 -0
  174. diffract/viz/styling/palettes/__init__.py +20 -0
  175. diffract/viz/styling/palettes/bundle.py +16 -0
  176. diffract/viz/styling/palettes/color.py +83 -0
  177. diffract/viz/styling/palettes/dashes.py +27 -0
  178. diffract/viz/styling/palettes/symbols.py +42 -0
  179. diffract/viz/styling/resolvers/__init__.py +11 -0
  180. diffract/viz/styling/resolvers/categorical.py +68 -0
  181. diffract/viz/styling/resolvers/color.py +77 -0
  182. diffract/viz/styling/resolvers/numeric.py +108 -0
  183. diffract/viz/styling/sources.py +27 -0
  184. diffract/viz/styling/theme/__init__.py +29 -0
  185. diffract/viz/styling/theme/applier.py +114 -0
  186. diffract/viz/styling/theme/components.py +66 -0
  187. diffract/viz/styling/theme/presets.py +58 -0
  188. diffract/viz/styling/theme/theme.py +36 -0
  189. diffract_core-0.2.1.dist-info/METADATA +530 -0
  190. diffract_core-0.2.1.dist-info/RECORD +193 -0
  191. diffract_core-0.2.1.dist-info/WHEEL +4 -0
  192. diffract_core-0.2.1.dist-info/licenses/LICENSE +201 -0
  193. diffract_core-0.2.1.dist-info/licenses/NOTICE +2 -0
@@ -0,0 +1,91 @@
1
+ """Visualization namespace for Session."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ from diffract.session.session import Session, SessionContext
9
+ from diffract.viz.renderer import render, render_from_config
10
+
11
+ from .box import box
12
+ from .grid import bound_grid, grid
13
+ from .heatmap import heatmap
14
+ from .scatter import scatter
15
+ from .sparkline import sparkline
16
+ from .violin import violin
17
+
18
+ if TYPE_CHECKING: # pragma: no cover
19
+ from diffract.viz.styling import Theme
20
+
21
+
22
+ class VizNamespace:
23
+ """Visualization API for Session.
24
+
25
+ Provides multiple ways to create visualizations:
26
+
27
+ 1. Simple methods (recommended for quick exploration):
28
+ >>> session.viz.box(y="stable_rank", x="model_id")
29
+ >>> session.viz.scatter(x="frob_norm", y="stable_rank")
30
+
31
+ 2. Plot objects (for Hydra configs and advanced customization):
32
+ >>> from diffract.viz.plots.boxplot import BoxPlot
33
+ >>> session.viz.draw(plot=BoxPlot(y="stable_rank", x="model_id"))
34
+
35
+ 3. Config files (for reproducible workflows):
36
+ >>> session.viz.draw(config_path="plots/boxplot.yaml")
37
+
38
+ 4. Grid helpers (for subplot dashboards and bound grids):
39
+ >>> session.viz.grid(subplots=[...])
40
+ >>> session.viz.bound_grid(plot_template=..., row=..., col=...)
41
+ """
42
+
43
+ def __init__(
44
+ self,
45
+ session_or_context: Session | SessionContext,
46
+ ) -> None:
47
+ self.__session_or_context = session_or_context
48
+
49
+ def draw(
50
+ self,
51
+ *,
52
+ plot: Any = None,
53
+ config_path: str | Path | None = None,
54
+ overrides: list[str] | None = None,
55
+ theme: Theme | None = None,
56
+ theme_path: str | Path | None = None,
57
+ ) -> Any:
58
+ """Render a Plotly figure using the viz module.
59
+
60
+ Provide either `plot` (a Plot object) or `config_path` (a Hydra YAML file).
61
+
62
+ Args:
63
+ plot: A Plot instance to render.
64
+ config_path: Path to a Hydra YAML config file.
65
+ overrides: Hydra overrides to apply (only with config_path).
66
+ theme: A Theme instance to apply.
67
+ theme_path: Path to a YAML file with theme config.
68
+ """
69
+ with self.__session_or_context:
70
+ if (plot is None) == (config_path is None):
71
+ raise ValueError("Provide exactly one of: plot=... or config_path=...")
72
+
73
+ if config_path is not None:
74
+ return render_from_config(
75
+ session=self.__session_or_context,
76
+ config_path=config_path,
77
+ overrides=overrides,
78
+ theme=theme,
79
+ theme_path=theme_path,
80
+ )
81
+
82
+ return render(plot, session=self.__session_or_context, theme=theme)
83
+
84
+ box = box
85
+ grid = grid
86
+ bound_grid = bound_grid
87
+ violin = violin
88
+ scatter = scatter
89
+ heatmap = heatmap
90
+ sparkline = sparkline
91
+ line = sparkline
@@ -0,0 +1,14 @@
1
+ """Shared helpers for viz namespace wrappers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+
8
+ def _to_field_ref(value: str | Any) -> Any:
9
+ """Convert str to FieldRef for plot constructor; pass through otherwise."""
10
+ from diffract.viz.data import FieldRef
11
+
12
+ if isinstance(value, str):
13
+ return FieldRef(field=value)
14
+ return value
@@ -0,0 +1,207 @@
1
+ """Box plot wrapper for Session.viz."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any, Literal
6
+
7
+ from diffract.session.namespaces.viz._utils import _to_field_ref
8
+ from diffract.viz.data import FieldRef
9
+
10
+ if TYPE_CHECKING:
11
+ from pathlib import Path
12
+
13
+ import plotly.graph_objects as go # type: ignore[import-not-found]
14
+
15
+ from diffract.viz.styling import Theme
16
+
17
+
18
+ def box(
19
+ self: Any,
20
+ *,
21
+ y: str | FieldRef,
22
+ x: str | FieldRef,
23
+ title: str | None = None,
24
+ value_filter: dict[str, tuple[str, Any]] | None = None,
25
+ box_width: float = 0.5,
26
+ boxpoints: Literal["all", "outliers", False] = "outliers",
27
+ jitter_enabled: bool = False,
28
+ jitter_width: float = 0.12,
29
+ jitter_offset: float = -0.35,
30
+ jitter_seed: int = 42,
31
+ jitter_density_scale: bool = True,
32
+ jitter_color: str | FieldRef | None = None,
33
+ jitter_colorscale: str = "Viridis",
34
+ x_title: str | None = None,
35
+ x_showticklabels: bool = True,
36
+ x_tickangle: int | None = None,
37
+ x_tickfont_size: int | None = None,
38
+ x_tickfont_family: str | None = None,
39
+ x_tickfont_color: str | None = None,
40
+ x_showgrid: bool = True,
41
+ x_gridcolor: str | None = None,
42
+ x_showline: bool = True,
43
+ x_linecolor: str | None = None,
44
+ y_title: str | None = None,
45
+ y_showticklabels: bool = True,
46
+ y_tickangle: int | None = None,
47
+ y_tickfont_size: int | None = None,
48
+ y_tickfont_family: str | None = None,
49
+ y_tickfont_color: str | None = None,
50
+ y_showgrid: bool = True,
51
+ y_gridcolor: str | None = None,
52
+ y_showline: bool = True,
53
+ y_linecolor: str | None = None,
54
+ y_range: tuple[float, float] | None = None,
55
+ y_dtick: float | str | None = None,
56
+ y_tick0: float | None = None,
57
+ y_tickformat: str | None = None,
58
+ y_zeroline: bool = False,
59
+ y_zerolinecolor: str | None = None,
60
+ marker_coloraxis_id: int | None = None,
61
+ marker_colorscale: str = "Viridis",
62
+ marker_showscale: bool = True,
63
+ marker_cmin: float | None = None,
64
+ marker_cmax: float | None = None,
65
+ marker_colorbar_title: str | None = None,
66
+ marker_coloraxis_override: bool = False,
67
+ marker_size: str | FieldRef | float | None = 6,
68
+ marker_size_range: tuple[float, float] | None = None,
69
+ marker_opacity: str | FieldRef | float | None = 0.7,
70
+ marker_opacity_range: tuple[float, float] | None = None,
71
+ marker_color: str | FieldRef | None = None,
72
+ marker_symbol: str | FieldRef | None = None,
73
+ theme: Theme | None = None,
74
+ theme_path: str | Path | None = None,
75
+ ) -> go.Figure:
76
+ """Create a box plot.
77
+
78
+ Args:
79
+ self: The bound viz namespace providing the draw() method.
80
+ y: Field for vertical values (field name or FieldRef).
81
+ x: Field for categories (field name or FieldRef).
82
+ title: Figure title.
83
+ value_filter: Filter entries by field values.
84
+ box_width: Width of boxes.
85
+ boxpoints: Show points: "all", "outliers", or False.
86
+ jitter_enabled: Enable the jitter overlay of individual points.
87
+ jitter_width: Horizontal spread of the jitter overlay.
88
+ jitter_offset: Horizontal offset of the jitter overlay from the box.
89
+ jitter_seed: Random seed for the jitter overlay.
90
+ jitter_density_scale: Scale jitter spread by local point density.
91
+ jitter_color: Field or color for jitter points.
92
+ jitter_colorscale: Colorscale for jitter points.
93
+ x_title: X-axis title.
94
+ x_showticklabels: Show x-axis tick labels.
95
+ x_tickangle: Angle of x-axis tick labels.
96
+ x_tickfont_size: Font size of x-axis tick labels.
97
+ x_tickfont_family: Font family of x-axis tick labels.
98
+ x_tickfont_color: Font color of x-axis tick labels.
99
+ x_showgrid: Show x-axis grid lines.
100
+ x_gridcolor: Color of x-axis grid lines.
101
+ x_showline: Show the x-axis line.
102
+ x_linecolor: Color of the x-axis line.
103
+ y_title: Y-axis title.
104
+ y_showticklabels: Show y-axis tick labels.
105
+ y_tickangle: Angle of y-axis tick labels.
106
+ y_tickfont_size: Font size of y-axis tick labels.
107
+ y_tickfont_family: Font family of y-axis tick labels.
108
+ y_tickfont_color: Font color of y-axis tick labels.
109
+ y_showgrid: Show y-axis grid lines.
110
+ y_gridcolor: Color of y-axis grid lines.
111
+ y_showline: Show the y-axis line.
112
+ y_linecolor: Color of the y-axis line.
113
+ y_range: Y-axis value range.
114
+ y_dtick: Y-axis tick step.
115
+ y_tick0: Y-axis starting tick.
116
+ y_tickformat: Y-axis tick format string.
117
+ y_zeroline: Show the y-axis zero line.
118
+ y_zerolinecolor: Color of the y-axis zero line.
119
+ marker_coloraxis_id: Shared color axis id for markers.
120
+ marker_colorscale: Colorscale for markers.
121
+ marker_showscale: Show the marker colorbar.
122
+ marker_cmin: Minimum value for marker color mapping.
123
+ marker_cmax: Maximum value for marker color mapping.
124
+ marker_colorbar_title: Title of the marker colorbar.
125
+ marker_coloraxis_override: Override the shared marker color axis.
126
+ marker_size: Field or fixed size for markers.
127
+ marker_size_range: Range to scale marker sizes into.
128
+ marker_opacity: Field or fixed opacity for markers.
129
+ marker_opacity_range: Range to scale marker opacity into.
130
+ marker_color: Field or color for markers.
131
+ marker_symbol: Field or symbol for markers.
132
+ theme: Theme to apply to the figure.
133
+ theme_path: Path to a theme file to apply to the figure.
134
+
135
+ Returns:
136
+ Plotly Figure.
137
+
138
+ Example:
139
+ >>> session.viz.box(y="stable_rank", x="model_id", marker_color="layer_id")
140
+ """
141
+ from diffract.viz.plots.boxplot import BoxPlot
142
+
143
+ plot = BoxPlot(
144
+ y=_to_field_ref(y),
145
+ x=_to_field_ref(x),
146
+ title=title,
147
+ value_filter=value_filter,
148
+ box_width=box_width,
149
+ boxpoints=boxpoints,
150
+ jitter_enabled=jitter_enabled,
151
+ jitter_width=jitter_width,
152
+ jitter_offset=jitter_offset,
153
+ jitter_seed=jitter_seed,
154
+ jitter_density_scale=jitter_density_scale,
155
+ jitter_color=_to_field_ref(jitter_color)
156
+ if isinstance(jitter_color, str)
157
+ else jitter_color,
158
+ jitter_colorscale=jitter_colorscale,
159
+ x_title=x_title,
160
+ x_showticklabels=x_showticklabels,
161
+ x_tickangle=x_tickangle,
162
+ x_tickfont_size=x_tickfont_size,
163
+ x_tickfont_family=x_tickfont_family,
164
+ x_tickfont_color=x_tickfont_color,
165
+ x_showgrid=x_showgrid,
166
+ x_gridcolor=x_gridcolor,
167
+ x_showline=x_showline,
168
+ x_linecolor=x_linecolor,
169
+ y_title=y_title,
170
+ y_showticklabels=y_showticklabels,
171
+ y_tickangle=y_tickangle,
172
+ y_tickfont_size=y_tickfont_size,
173
+ y_tickfont_family=y_tickfont_family,
174
+ y_tickfont_color=y_tickfont_color,
175
+ y_showgrid=y_showgrid,
176
+ y_gridcolor=y_gridcolor,
177
+ y_showline=y_showline,
178
+ y_linecolor=y_linecolor,
179
+ y_range=y_range,
180
+ y_dtick=y_dtick,
181
+ y_tick0=y_tick0,
182
+ y_tickformat=y_tickformat,
183
+ y_zeroline=y_zeroline,
184
+ y_zerolinecolor=y_zerolinecolor,
185
+ marker_coloraxis_id=marker_coloraxis_id,
186
+ marker_colorscale=marker_colorscale,
187
+ marker_showscale=marker_showscale,
188
+ marker_cmin=marker_cmin,
189
+ marker_cmax=marker_cmax,
190
+ marker_colorbar_title=marker_colorbar_title,
191
+ marker_coloraxis_override=marker_coloraxis_override,
192
+ marker_size=_to_field_ref(marker_size)
193
+ if isinstance(marker_size, str)
194
+ else marker_size,
195
+ marker_size_range=marker_size_range,
196
+ marker_opacity=_to_field_ref(marker_opacity)
197
+ if isinstance(marker_opacity, str)
198
+ else marker_opacity,
199
+ marker_opacity_range=marker_opacity_range,
200
+ marker_color=_to_field_ref(marker_color)
201
+ if isinstance(marker_color, str)
202
+ else marker_color,
203
+ marker_symbol=_to_field_ref(marker_symbol)
204
+ if isinstance(marker_symbol, str)
205
+ else marker_symbol,
206
+ )
207
+ return self.draw(plot=plot, theme=theme, theme_path=theme_path)
@@ -0,0 +1,160 @@
1
+ """Grid plot wrappers for Session.viz."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import replace
6
+ from pathlib import Path
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ from diffract.session.namespaces.viz._utils import _to_field_ref
10
+
11
+ if TYPE_CHECKING:
12
+ import plotly.graph_objects as go # type: ignore[import-not-found]
13
+
14
+ from diffract.viz.plots.base.plot import Plot
15
+ from diffract.viz.plots.subplots import GridAxisBind, GridCellRule, SubplotSpec
16
+ from diffract.viz.styling import Theme
17
+
18
+
19
+ def grid(
20
+ self: Any,
21
+ *,
22
+ subplots: list[SubplotSpec],
23
+ make_subplots_kwargs: dict[str, Any] | None = None,
24
+ theme: Theme | None = None,
25
+ theme_path: str | Path | None = None,
26
+ ) -> go.Figure:
27
+ """Create and render a `GridPlot` from explicit subplot specifications."""
28
+ from diffract.viz.plots.subplots import GridPlot
29
+
30
+ plot = GridPlot(
31
+ subplots=subplots,
32
+ make_subplots_kwargs=dict(make_subplots_kwargs or {}),
33
+ )
34
+ return self.draw(plot=plot, theme=theme, theme_path=theme_path)
35
+
36
+
37
+ def bound_grid(
38
+ self: Any,
39
+ *,
40
+ plot_template: Plot,
41
+ row: GridAxisBind | None = None,
42
+ col: GridAxisBind | None = None,
43
+ cell_rules: list[GridCellRule] | None = None,
44
+ title_template: str | None = None,
45
+ make_subplots_kwargs: dict[str, Any] | None = None,
46
+ base_session_filter: dict[str, Any] | None = None,
47
+ base_value_filter: dict[str, tuple[str, Any]] | None = None,
48
+ theme: Theme | None = None,
49
+ theme_path: str | Path | None = None,
50
+ ) -> go.Figure:
51
+ """Create and render a bound grid generated from row/column axis binds.
52
+
53
+ For `plot` binds targeting `FieldRef` plot attributes, plain string bind
54
+ values are automatically converted into `FieldRef(field=...)`. The same
55
+ conversion is applied to `cell_rules[*].plot` overrides.
56
+ """
57
+ from diffract.viz.plots.subplots import build_bound_grid
58
+
59
+ resolved_row = _coerce_plot_bind_field_refs(plot_template=plot_template, bind=row)
60
+ resolved_col = _coerce_plot_bind_field_refs(plot_template=plot_template, bind=col)
61
+ resolved_rules = _coerce_rule_plot_field_refs(
62
+ plot_template=plot_template,
63
+ rules=cell_rules,
64
+ )
65
+
66
+ plot = build_bound_grid(
67
+ plot_template=plot_template,
68
+ row=resolved_row,
69
+ col=resolved_col,
70
+ cell_rules=resolved_rules,
71
+ title_template=title_template,
72
+ make_subplots_kwargs=make_subplots_kwargs,
73
+ base_session_filter=base_session_filter,
74
+ base_value_filter=base_value_filter,
75
+ )
76
+ return self.draw(plot=plot, theme=theme, theme_path=theme_path)
77
+
78
+
79
+ def _coerce_plot_bind_field_refs(
80
+ *,
81
+ plot_template: Plot,
82
+ bind: GridAxisBind | None,
83
+ ) -> GridAxisBind | None:
84
+ """Convert string plot-bind values to FieldRef when template field is FieldRef."""
85
+ if bind is None or bind.target != "plot":
86
+ return bind
87
+
88
+ if not hasattr(plot_template, bind.key):
89
+ return bind
90
+
91
+ from diffract.viz.data import FieldRef
92
+
93
+ template_value = getattr(plot_template, bind.key)
94
+ if not isinstance(template_value, FieldRef):
95
+ return bind
96
+
97
+ changed = False
98
+ converted_values: list[Any] = []
99
+ for value in bind.values:
100
+ if isinstance(value, str):
101
+ converted_values.append(_to_field_ref(value))
102
+ changed = True
103
+ continue
104
+ converted_values.append(value)
105
+
106
+ if not changed:
107
+ return bind
108
+
109
+ return replace(bind, values=tuple(converted_values))
110
+
111
+
112
+ def _coerce_rule_plot_field_refs(
113
+ *,
114
+ plot_template: Plot,
115
+ rules: list[GridCellRule] | None,
116
+ ) -> list[GridCellRule] | None:
117
+ """Convert string `cell_rules[*].plot` values to FieldRef when needed."""
118
+ if not rules:
119
+ return rules
120
+
121
+ changed = False
122
+ converted_rules: list[GridCellRule] = []
123
+ for rule in rules:
124
+ converted_rule, rule_changed = _coerce_single_rule_plot_field_refs(
125
+ plot_template=plot_template,
126
+ rule=rule,
127
+ )
128
+ converted_rules.append(converted_rule)
129
+ changed = changed or rule_changed
130
+
131
+ if not changed:
132
+ return rules
133
+ return converted_rules
134
+
135
+
136
+ def _coerce_single_rule_plot_field_refs(
137
+ *,
138
+ plot_template: Plot,
139
+ rule: GridCellRule,
140
+ ) -> tuple[GridCellRule, bool]:
141
+ """Convert one rule's `plot` overrides where template fields are FieldRef."""
142
+ if not rule.plot:
143
+ return rule, False
144
+
145
+ from diffract.viz.data import FieldRef
146
+
147
+ changed = False
148
+ converted_plot = dict(rule.plot)
149
+ for key, value in rule.plot.items():
150
+ if not hasattr(plot_template, key):
151
+ continue
152
+
153
+ template_value = getattr(plot_template, key)
154
+ if isinstance(template_value, FieldRef) and isinstance(value, str):
155
+ converted_plot[key] = _to_field_ref(value)
156
+ changed = True
157
+
158
+ if not changed:
159
+ return rule, False
160
+ return replace(rule, plot=converted_plot), True
@@ -0,0 +1,164 @@
1
+ """Heatmap plot wrapper for Session.viz."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ from diffract.session.namespaces.viz._utils import _to_field_ref
8
+ from diffract.viz.data import FieldRef
9
+
10
+ if TYPE_CHECKING:
11
+ from pathlib import Path
12
+
13
+ import plotly.graph_objects as go # type: ignore[import-not-found]
14
+
15
+ from diffract.viz.styling import Theme
16
+
17
+
18
+ def heatmap(
19
+ self: Any,
20
+ *,
21
+ z: str | FieldRef,
22
+ x: str | FieldRef,
23
+ y: str | FieldRef,
24
+ title: str | None = None,
25
+ value_filter: dict[str, tuple[str, Any]] | None = None,
26
+ fill_value: float = float("nan"),
27
+ show_text: bool = False,
28
+ text_format: str = ".2f",
29
+ text_font_size: int = 10,
30
+ reverse_y: bool = True,
31
+ x_title: str | None = None,
32
+ x_showticklabels: bool = True,
33
+ x_tickangle: int | None = None,
34
+ x_tickfont_size: int | None = None,
35
+ x_tickfont_family: str | None = None,
36
+ x_tickfont_color: str | None = None,
37
+ x_showgrid: bool = True,
38
+ x_gridcolor: str | None = None,
39
+ x_showline: bool = True,
40
+ x_linecolor: str | None = None,
41
+ x_categoryorder: str | None = None,
42
+ x_categoryarray: list[str] | None = None,
43
+ y_title: str | None = None,
44
+ y_showticklabels: bool = True,
45
+ y_tickangle: int | None = None,
46
+ y_tickfont_size: int | None = None,
47
+ y_tickfont_family: str | None = None,
48
+ y_tickfont_color: str | None = None,
49
+ y_showgrid: bool = True,
50
+ y_gridcolor: str | None = None,
51
+ y_showline: bool = True,
52
+ y_linecolor: str | None = None,
53
+ y_categoryorder: str | None = None,
54
+ y_categoryarray: list[str] | None = None,
55
+ heatmap_coloraxis_id: int | None = None,
56
+ heatmap_colorscale: str = "Viridis",
57
+ heatmap_showscale: bool = True,
58
+ heatmap_cmin: float | None = None,
59
+ heatmap_cmax: float | None = None,
60
+ heatmap_colorbar_title: str | None = None,
61
+ heatmap_coloraxis_override: bool = False,
62
+ theme: Theme | None = None,
63
+ theme_path: str | Path | None = None,
64
+ ) -> go.Figure:
65
+ """Create a heatmap by pivoting a scalar field.
66
+
67
+ Args:
68
+ self: The bound viz namespace providing the draw() method.
69
+ z: Field for cell values (field name or FieldRef).
70
+ x: Field for columns (field name or FieldRef).
71
+ y: Field for rows (field name or FieldRef).
72
+ title: Figure title.
73
+ value_filter: Filter entries by field values.
74
+ fill_value: Value for missing (x, y) cells.
75
+ show_text: Show cell values as text.
76
+ text_format: Format string for text (e.g. ".2f").
77
+ text_font_size: Font size for cell text.
78
+ reverse_y: Reverse y-axis so first row is at top.
79
+ x_title: X-axis title.
80
+ x_showticklabels: Show x-axis tick labels.
81
+ x_tickangle: Angle of x-axis tick labels.
82
+ x_tickfont_size: Font size of x-axis tick labels.
83
+ x_tickfont_family: Font family of x-axis tick labels.
84
+ x_tickfont_color: Font color of x-axis tick labels.
85
+ x_showgrid: Show x-axis grid lines.
86
+ x_gridcolor: Color of x-axis grid lines.
87
+ x_showline: Show the x-axis line.
88
+ x_linecolor: Color of the x-axis line.
89
+ x_categoryorder: Ordering strategy for x-axis categories.
90
+ x_categoryarray: Explicit ordering of x-axis categories.
91
+ y_title: Y-axis title.
92
+ y_showticklabels: Show y-axis tick labels.
93
+ y_tickangle: Angle of y-axis tick labels.
94
+ y_tickfont_size: Font size of y-axis tick labels.
95
+ y_tickfont_family: Font family of y-axis tick labels.
96
+ y_tickfont_color: Font color of y-axis tick labels.
97
+ y_showgrid: Show y-axis grid lines.
98
+ y_gridcolor: Color of y-axis grid lines.
99
+ y_showline: Show the y-axis line.
100
+ y_linecolor: Color of the y-axis line.
101
+ y_categoryorder: Ordering strategy for y-axis categories.
102
+ y_categoryarray: Explicit ordering of y-axis categories.
103
+ heatmap_coloraxis_id: Shared color axis id for the heatmap.
104
+ heatmap_colorscale: Colorscale for the heatmap.
105
+ heatmap_showscale: Show the heatmap colorbar.
106
+ heatmap_cmin: Minimum value for heatmap color mapping.
107
+ heatmap_cmax: Maximum value for heatmap color mapping.
108
+ heatmap_colorbar_title: Title of the heatmap colorbar.
109
+ heatmap_coloraxis_override: Override the shared heatmap color axis.
110
+ theme: Theme to apply to the figure.
111
+ theme_path: Path to a theme file to apply to the figure.
112
+
113
+ Returns:
114
+ Plotly Figure.
115
+
116
+ Example:
117
+ >>> session.viz.heatmap(z="stable_rank", x="head_id", y="layer_id")
118
+ """
119
+ from diffract.viz.plots.heatmap import HeatmapPlot
120
+
121
+ plot = HeatmapPlot(
122
+ z=_to_field_ref(z),
123
+ x=_to_field_ref(x),
124
+ y=_to_field_ref(y),
125
+ title=title,
126
+ value_filter=value_filter,
127
+ fill_value=fill_value,
128
+ show_text=show_text,
129
+ text_format=text_format,
130
+ text_font_size=text_font_size,
131
+ reverse_y=reverse_y,
132
+ x_title=x_title,
133
+ x_showticklabels=x_showticklabels,
134
+ x_tickangle=x_tickangle,
135
+ x_tickfont_size=x_tickfont_size,
136
+ x_tickfont_family=x_tickfont_family,
137
+ x_tickfont_color=x_tickfont_color,
138
+ x_showgrid=x_showgrid,
139
+ x_gridcolor=x_gridcolor,
140
+ x_showline=x_showline,
141
+ x_linecolor=x_linecolor,
142
+ x_categoryorder=x_categoryorder,
143
+ x_categoryarray=x_categoryarray,
144
+ y_title=y_title,
145
+ y_showticklabels=y_showticklabels,
146
+ y_tickangle=y_tickangle,
147
+ y_tickfont_size=y_tickfont_size,
148
+ y_tickfont_family=y_tickfont_family,
149
+ y_tickfont_color=y_tickfont_color,
150
+ y_showgrid=y_showgrid,
151
+ y_gridcolor=y_gridcolor,
152
+ y_showline=y_showline,
153
+ y_linecolor=y_linecolor,
154
+ y_categoryorder=y_categoryorder,
155
+ y_categoryarray=y_categoryarray,
156
+ heatmap_coloraxis_id=heatmap_coloraxis_id,
157
+ heatmap_colorscale=heatmap_colorscale,
158
+ heatmap_showscale=heatmap_showscale,
159
+ heatmap_cmin=heatmap_cmin,
160
+ heatmap_cmax=heatmap_cmax,
161
+ heatmap_colorbar_title=heatmap_colorbar_title,
162
+ heatmap_coloraxis_override=heatmap_coloraxis_override,
163
+ )
164
+ return self.draw(plot=plot, theme=theme, theme_path=theme_path)