tensor-network-visualization 1.5.1__tar.gz → 1.5.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.
- {tensor_network_visualization-1.5.1/src/tensor_network_visualization.egg-info → tensor_network_visualization-1.5.2}/PKG-INFO +14 -6
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/README.md +13 -5
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/pyproject.toml +5 -3
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2/src/tensor_network_visualization.egg-info}/PKG-INFO +14 -6
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_visualization.egg-info/SOURCES.txt +11 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_core/_draw_common.py +9 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/contraction_edges.py +3 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/dangling_self_edges.py +53 -17
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/edge_labels.py +14 -5
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/edge_orchestration.py +7 -1
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/fonts_and_scale.py +184 -182
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/graph_pipeline.py +23 -56
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/hover.py +22 -11
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_core/draw/label_descriptors.py +56 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/labels_misc.py +158 -154
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/plotter.py +312 -304
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/render_prep.py +74 -11
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/scene_state.py +5 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/tensors.py +30 -6
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/viewport_geometry.py +19 -1
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/graph.py +5 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/graph_cache.py +60 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/direction_common.py +528 -477
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_core/layout/free_directions_2d.py +920 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_core/layout/free_directions_3d.py +495 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/geometry.py +21 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/renderer.py +11 -2
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_input_inspection.py +157 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/__init__.py +3 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/bridge.py +164 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/controller.py +662 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/scheme.py +245 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/state.py +88 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_interactive_scene.py +493 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_matplotlib_state.py +55 -0
- tensor_network_visualization-1.5.1/src/tensor_network_viz/tensor_elements.py → tensor_network_visualization-1.5.2/src/tensor_network_viz/_tensor_elements_controller.py +239 -87
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_tensor_elements_data.py +190 -88
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_tensor_elements_payloads.py +99 -14
- tensor_network_visualization-1.5.2/src/tensor_network_viz/_ui_utils.py +69 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/config.py +7 -4
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/contraction_viewer.py +152 -49
- tensor_network_visualization-1.5.2/src/tensor_network_viz/einsum_module/contraction_cost.py +150 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/graph.py +22 -7
- tensor_network_visualization-1.5.2/src/tensor_network_viz/interactive_viewer.py +7 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/tensor_elements.py +99 -0
- tensor_network_visualization-1.5.2/src/tensor_network_viz/tensor_elements_config.py +60 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/viewer.py +10 -80
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_ci_workflow.py +9 -2
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_contraction_cost.py +105 -6
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_contraction_viewer.py +38 -4
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_demo_cli_scheme.py +17 -1
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_draw_performance.py +3 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_einsum_backend.py +41 -1
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_engineering_baseline.py +54 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_examples.py +180 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_graph_cache.py +45 -0
- tensor_network_visualization-1.5.2/tests/test_interaction_state.py +165 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_label_draw_metrics_perf.py +3 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_layout_core.py +591 -9
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_node_degrees_perf.py +2 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_plotting.py +433 -8
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_public_api.py +1 -0
- tensor_network_visualization-1.5.2/tests/test_show_tensor_network_throughput.py +172 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_tensor_elements.py +476 -6
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_tensor_elements_perf.py +2 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_verify_script.py +1 -1
- tensor_network_visualization-1.5.1/src/tensor_network_viz/_core/_draw_common.py +0 -6
- tensor_network_visualization-1.5.1/src/tensor_network_viz/_core/layout/free_directions_2d.py +0 -493
- tensor_network_visualization-1.5.1/src/tensor_network_viz/_core/layout/free_directions_3d.py +0 -250
- tensor_network_visualization-1.5.1/src/tensor_network_viz/_ui_utils.py +0 -33
- tensor_network_visualization-1.5.1/src/tensor_network_viz/einsum_module/contraction_cost.py +0 -79
- tensor_network_visualization-1.5.1/src/tensor_network_viz/interactive_viewer.py +0 -572
- tensor_network_visualization-1.5.1/src/tensor_network_viz/tensor_elements_config.py +0 -34
- tensor_network_visualization-1.5.1/tests/test_show_tensor_network_throughput.py +0 -57
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/LICENSE +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/setup.cfg +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_visualization.egg-info/dependency_links.txt +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_visualization.egg-info/requires.txt +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_visualization.egg-info/top_level.txt +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/_label_format.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/_nodes_edges_common.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/axis_directions.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/contractions.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/curves.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/constants.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/contraction_scheme.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/disk_metrics.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/edges.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/pick_distance.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/vectors.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/graph_utils.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/body.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/force_directed.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/parameters.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/positions.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/types.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout_structure.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_engine_specs.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_registry.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_tensor_elements_support.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_typing.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/_backend.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/_equation.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/_trace_state.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/_trace_types.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/renderer.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/trace.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/py.typed +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/quimb/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/quimb/graph.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/quimb/renderer.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tenpy/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tenpy/explicit.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tenpy/graph.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tenpy/renderer.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensorkrowch/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensorkrowch/graph.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensorkrowch/renderer.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensornetwork/__init__.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensornetwork/graph.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensornetwork/renderer.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_contraction_groups_once.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_contraction_scheme.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_edge_index_label_2d.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_edge_index_label_3d.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_einsum_autotrace.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_engine_detection.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_examples_structure.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_integration_einsum.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_integration_tensorkrowch.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_integration_tensornetwork.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_label_format.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_lazy_imports.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_packaging_metadata.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_quimb_backend.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_render_performance_controls.py +0 -0
- {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_tenpy_backend.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tensor-network-visualization
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.2
|
|
4
4
|
Summary: Minimal Matplotlib visualizations for TensorKrowch, TensorNetwork, Quimb, TeNPy, and traced PyTorch/NumPy einsum tensor networks.
|
|
5
5
|
Author: Alejandro Mata Ali
|
|
6
6
|
License-Expression: MIT
|
|
@@ -171,13 +171,14 @@ show_tensor_elements(
|
|
|
171
171
|
|
|
172
172
|
When several tensors are present, the figure keeps one tensor active at a time and uses a slider
|
|
173
173
|
to switch between them. The interactive controls are grouped: `basic` (`elements`, `magnitude`,
|
|
174
|
-
`distribution`, `data`), `complex` (`real`, `imag`, `phase`), and
|
|
175
|
-
`signed_value`).
|
|
174
|
+
`log_magnitude`, `distribution`, `data`), `complex` (`real`, `imag`, `phase`), and
|
|
175
|
+
`diagnostic` (`sign`, `signed_value`, `sparsity`, `nan_inf`).
|
|
176
176
|
|
|
177
177
|
- `data`: single tensor, iterable of tensors, supported backend-native tensor collections, or an
|
|
178
178
|
`EinsumTrace` with live tensor values.
|
|
179
179
|
- `engine`: optional backend override. If omitted, the library auto-detects it.
|
|
180
180
|
- `config`: tensor-inspection behavior lives here.
|
|
181
|
+
- `data` mode now includes global stats, per-axis summaries, and top-k coordinates by magnitude.
|
|
181
182
|
- `ax`: render a single tensor into an existing Matplotlib axis.
|
|
182
183
|
- `show_controls`: if `True`, add compact Matplotlib `group + mode` controls and, when needed, a tensor slider.
|
|
183
184
|
- `show`: if `False`, nothing is displayed automatically.
|
|
@@ -220,6 +221,10 @@ config = TensorElementsConfig(
|
|
|
220
221
|
mode="auto",
|
|
221
222
|
max_matrix_shape=(256, 256),
|
|
222
223
|
histogram_bins=40,
|
|
224
|
+
topk_count=8,
|
|
225
|
+
robust_percentiles=(1.0, 99.0),
|
|
226
|
+
shared_color_scale=False,
|
|
227
|
+
highlight_outliers=False,
|
|
223
228
|
)
|
|
224
229
|
```
|
|
225
230
|
|
|
@@ -228,10 +233,13 @@ This is where you configure:
|
|
|
228
233
|
- the active inspection mode,
|
|
229
234
|
- row/column axis grouping for rank > 2 tensors,
|
|
230
235
|
- heatmap downsampling limits,
|
|
231
|
-
- histogram sampling and bin count
|
|
236
|
+
- histogram sampling and bin count,
|
|
237
|
+
- data-summary depth (`topk_count`),
|
|
238
|
+
- optional robust/shared scaling and outlier overlays.
|
|
232
239
|
|
|
233
240
|
If you want to start in a specific grouped view, pass `mode="real"`, `mode="imag"`,
|
|
234
|
-
`mode="phase"`, `mode="
|
|
241
|
+
`mode="phase"`, `mode="log_magnitude"`, `mode="sparsity"`, `mode="nan_inf"`, `mode="sign"`, or
|
|
242
|
+
`mode="signed_value"` directly in
|
|
235
243
|
`TensorElementsConfig(...)`.
|
|
236
244
|
|
|
237
245
|
## Most Common Workflows
|
|
@@ -397,7 +405,7 @@ For fuller backend examples, see [docs/backends.md](docs/backends.md).
|
|
|
397
405
|
| `hover_labels` | Enable hover tooltips in interactive sessions. |
|
|
398
406
|
| `show_contraction_scheme` | Draw contraction-step regions. |
|
|
399
407
|
| `contraction_playback` | Start with playback controls enabled when controls are shown. |
|
|
400
|
-
| `contraction_scheme_cost_hover` | Show
|
|
408
|
+
| `contraction_scheme_cost_hover` | Show contraction details in the playback panel. |
|
|
401
409
|
| `tensor_label_refinement` | `"auto"`, `"always"`, or `"never"` for the expensive label-fit pass. |
|
|
402
410
|
| `layout_iterations` | Force-layout effort. |
|
|
403
411
|
| `positions` | Supply custom node coordinates. |
|
|
@@ -120,13 +120,14 @@ show_tensor_elements(
|
|
|
120
120
|
|
|
121
121
|
When several tensors are present, the figure keeps one tensor active at a time and uses a slider
|
|
122
122
|
to switch between them. The interactive controls are grouped: `basic` (`elements`, `magnitude`,
|
|
123
|
-
`distribution`, `data`), `complex` (`real`, `imag`, `phase`), and
|
|
124
|
-
`signed_value`).
|
|
123
|
+
`log_magnitude`, `distribution`, `data`), `complex` (`real`, `imag`, `phase`), and
|
|
124
|
+
`diagnostic` (`sign`, `signed_value`, `sparsity`, `nan_inf`).
|
|
125
125
|
|
|
126
126
|
- `data`: single tensor, iterable of tensors, supported backend-native tensor collections, or an
|
|
127
127
|
`EinsumTrace` with live tensor values.
|
|
128
128
|
- `engine`: optional backend override. If omitted, the library auto-detects it.
|
|
129
129
|
- `config`: tensor-inspection behavior lives here.
|
|
130
|
+
- `data` mode now includes global stats, per-axis summaries, and top-k coordinates by magnitude.
|
|
130
131
|
- `ax`: render a single tensor into an existing Matplotlib axis.
|
|
131
132
|
- `show_controls`: if `True`, add compact Matplotlib `group + mode` controls and, when needed, a tensor slider.
|
|
132
133
|
- `show`: if `False`, nothing is displayed automatically.
|
|
@@ -169,6 +170,10 @@ config = TensorElementsConfig(
|
|
|
169
170
|
mode="auto",
|
|
170
171
|
max_matrix_shape=(256, 256),
|
|
171
172
|
histogram_bins=40,
|
|
173
|
+
topk_count=8,
|
|
174
|
+
robust_percentiles=(1.0, 99.0),
|
|
175
|
+
shared_color_scale=False,
|
|
176
|
+
highlight_outliers=False,
|
|
172
177
|
)
|
|
173
178
|
```
|
|
174
179
|
|
|
@@ -177,10 +182,13 @@ This is where you configure:
|
|
|
177
182
|
- the active inspection mode,
|
|
178
183
|
- row/column axis grouping for rank > 2 tensors,
|
|
179
184
|
- heatmap downsampling limits,
|
|
180
|
-
- histogram sampling and bin count
|
|
185
|
+
- histogram sampling and bin count,
|
|
186
|
+
- data-summary depth (`topk_count`),
|
|
187
|
+
- optional robust/shared scaling and outlier overlays.
|
|
181
188
|
|
|
182
189
|
If you want to start in a specific grouped view, pass `mode="real"`, `mode="imag"`,
|
|
183
|
-
`mode="phase"`, `mode="
|
|
190
|
+
`mode="phase"`, `mode="log_magnitude"`, `mode="sparsity"`, `mode="nan_inf"`, `mode="sign"`, or
|
|
191
|
+
`mode="signed_value"` directly in
|
|
184
192
|
`TensorElementsConfig(...)`.
|
|
185
193
|
|
|
186
194
|
## Most Common Workflows
|
|
@@ -346,7 +354,7 @@ For fuller backend examples, see [docs/backends.md](docs/backends.md).
|
|
|
346
354
|
| `hover_labels` | Enable hover tooltips in interactive sessions. |
|
|
347
355
|
| `show_contraction_scheme` | Draw contraction-step regions. |
|
|
348
356
|
| `contraction_playback` | Start with playback controls enabled when controls are shown. |
|
|
349
|
-
| `contraction_scheme_cost_hover` | Show
|
|
357
|
+
| `contraction_scheme_cost_hover` | Show contraction details in the playback panel. |
|
|
350
358
|
| `tensor_label_refinement` | `"auto"`, `"always"`, or `"never"` for the expensive label-fit pass. |
|
|
351
359
|
| `layout_iterations` | Force-layout effort. |
|
|
352
360
|
| `positions` | Supply custom node coordinates. |
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tensor-network-visualization"
|
|
7
|
-
version = "1.5.
|
|
7
|
+
version = "1.5.2"
|
|
8
8
|
description = "Minimal Matplotlib visualizations for TensorKrowch, TensorNetwork, Quimb, TeNPy, and traced PyTorch/NumPy einsum tensor networks."
|
|
9
9
|
authors = [{ name = "Alejandro Mata Ali" }]
|
|
10
10
|
readme = "README.md"
|
|
@@ -62,6 +62,10 @@ tensor_network_viz = ["py.typed"]
|
|
|
62
62
|
testpaths = ["tests"]
|
|
63
63
|
addopts = "-p no:cacheprovider"
|
|
64
64
|
pythonpath = ["src"]
|
|
65
|
+
markers = [
|
|
66
|
+
"perf: runtime-sensitive regression checks and throughput guards",
|
|
67
|
+
"smoke: lightweight render smoke checks",
|
|
68
|
+
]
|
|
65
69
|
|
|
66
70
|
[tool.ruff]
|
|
67
71
|
line-length = 100
|
|
@@ -77,6 +81,4 @@ select = ["E", "F", "I", "B", "UP", "C4", "SIM", "RUF100"]
|
|
|
77
81
|
"examples/**/*.py" = ["E402"]
|
|
78
82
|
# Repo-root bench helpers insert ``src`` on sys.path before third-party imports.
|
|
79
83
|
"scripts/**/*.py" = ["E402"]
|
|
80
|
-
# Draw/layout splits mirror the old monolith: submodule star-import of tuning constants.
|
|
81
|
-
"src/tensor_network_viz/_core/draw/*.py" = ["F403", "F405"]
|
|
82
84
|
"src/tensor_network_viz/_core/layout/body.py" = ["F403", "F405"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tensor-network-visualization
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.2
|
|
4
4
|
Summary: Minimal Matplotlib visualizations for TensorKrowch, TensorNetwork, Quimb, TeNPy, and traced PyTorch/NumPy einsum tensor networks.
|
|
5
5
|
Author: Alejandro Mata Ali
|
|
6
6
|
License-Expression: MIT
|
|
@@ -171,13 +171,14 @@ show_tensor_elements(
|
|
|
171
171
|
|
|
172
172
|
When several tensors are present, the figure keeps one tensor active at a time and uses a slider
|
|
173
173
|
to switch between them. The interactive controls are grouped: `basic` (`elements`, `magnitude`,
|
|
174
|
-
`distribution`, `data`), `complex` (`real`, `imag`, `phase`), and
|
|
175
|
-
`signed_value`).
|
|
174
|
+
`log_magnitude`, `distribution`, `data`), `complex` (`real`, `imag`, `phase`), and
|
|
175
|
+
`diagnostic` (`sign`, `signed_value`, `sparsity`, `nan_inf`).
|
|
176
176
|
|
|
177
177
|
- `data`: single tensor, iterable of tensors, supported backend-native tensor collections, or an
|
|
178
178
|
`EinsumTrace` with live tensor values.
|
|
179
179
|
- `engine`: optional backend override. If omitted, the library auto-detects it.
|
|
180
180
|
- `config`: tensor-inspection behavior lives here.
|
|
181
|
+
- `data` mode now includes global stats, per-axis summaries, and top-k coordinates by magnitude.
|
|
181
182
|
- `ax`: render a single tensor into an existing Matplotlib axis.
|
|
182
183
|
- `show_controls`: if `True`, add compact Matplotlib `group + mode` controls and, when needed, a tensor slider.
|
|
183
184
|
- `show`: if `False`, nothing is displayed automatically.
|
|
@@ -220,6 +221,10 @@ config = TensorElementsConfig(
|
|
|
220
221
|
mode="auto",
|
|
221
222
|
max_matrix_shape=(256, 256),
|
|
222
223
|
histogram_bins=40,
|
|
224
|
+
topk_count=8,
|
|
225
|
+
robust_percentiles=(1.0, 99.0),
|
|
226
|
+
shared_color_scale=False,
|
|
227
|
+
highlight_outliers=False,
|
|
223
228
|
)
|
|
224
229
|
```
|
|
225
230
|
|
|
@@ -228,10 +233,13 @@ This is where you configure:
|
|
|
228
233
|
- the active inspection mode,
|
|
229
234
|
- row/column axis grouping for rank > 2 tensors,
|
|
230
235
|
- heatmap downsampling limits,
|
|
231
|
-
- histogram sampling and bin count
|
|
236
|
+
- histogram sampling and bin count,
|
|
237
|
+
- data-summary depth (`topk_count`),
|
|
238
|
+
- optional robust/shared scaling and outlier overlays.
|
|
232
239
|
|
|
233
240
|
If you want to start in a specific grouped view, pass `mode="real"`, `mode="imag"`,
|
|
234
|
-
`mode="phase"`, `mode="
|
|
241
|
+
`mode="phase"`, `mode="log_magnitude"`, `mode="sparsity"`, `mode="nan_inf"`, `mode="sign"`, or
|
|
242
|
+
`mode="signed_value"` directly in
|
|
235
243
|
`TensorElementsConfig(...)`.
|
|
236
244
|
|
|
237
245
|
## Most Common Workflows
|
|
@@ -397,7 +405,7 @@ For fuller backend examples, see [docs/backends.md](docs/backends.md).
|
|
|
397
405
|
| `hover_labels` | Enable hover tooltips in interactive sessions. |
|
|
398
406
|
| `show_contraction_scheme` | Draw contraction-step regions. |
|
|
399
407
|
| `contraction_playback` | Start with playback controls enabled when controls are shown. |
|
|
400
|
-
| `contraction_scheme_cost_hover` | Show
|
|
408
|
+
| `contraction_scheme_cost_hover` | Show contraction details in the playback panel. |
|
|
401
409
|
| `tensor_label_refinement` | `"auto"`, `"always"`, or `"never"` for the expensive label-fit pass. |
|
|
402
410
|
| `layout_iterations` | Force-layout effort. |
|
|
403
411
|
| `positions` | Supply custom node coordinates. |
|
|
@@ -8,7 +8,11 @@ src/tensor_network_visualization.egg-info/requires.txt
|
|
|
8
8
|
src/tensor_network_visualization.egg-info/top_level.txt
|
|
9
9
|
src/tensor_network_viz/__init__.py
|
|
10
10
|
src/tensor_network_viz/_engine_specs.py
|
|
11
|
+
src/tensor_network_viz/_input_inspection.py
|
|
12
|
+
src/tensor_network_viz/_interactive_scene.py
|
|
13
|
+
src/tensor_network_viz/_matplotlib_state.py
|
|
11
14
|
src/tensor_network_viz/_registry.py
|
|
15
|
+
src/tensor_network_viz/_tensor_elements_controller.py
|
|
12
16
|
src/tensor_network_viz/_tensor_elements_data.py
|
|
13
17
|
src/tensor_network_viz/_tensor_elements_payloads.py
|
|
14
18
|
src/tensor_network_viz/_tensor_elements_support.py
|
|
@@ -45,6 +49,7 @@ src/tensor_network_viz/_core/draw/edges.py
|
|
|
45
49
|
src/tensor_network_viz/_core/draw/fonts_and_scale.py
|
|
46
50
|
src/tensor_network_viz/_core/draw/graph_pipeline.py
|
|
47
51
|
src/tensor_network_viz/_core/draw/hover.py
|
|
52
|
+
src/tensor_network_viz/_core/draw/label_descriptors.py
|
|
48
53
|
src/tensor_network_viz/_core/draw/labels_misc.py
|
|
49
54
|
src/tensor_network_viz/_core/draw/pick_distance.py
|
|
50
55
|
src/tensor_network_viz/_core/draw/plotter.py
|
|
@@ -63,6 +68,11 @@ src/tensor_network_viz/_core/layout/geometry.py
|
|
|
63
68
|
src/tensor_network_viz/_core/layout/parameters.py
|
|
64
69
|
src/tensor_network_viz/_core/layout/positions.py
|
|
65
70
|
src/tensor_network_viz/_core/layout/types.py
|
|
71
|
+
src/tensor_network_viz/_interaction/__init__.py
|
|
72
|
+
src/tensor_network_viz/_interaction/bridge.py
|
|
73
|
+
src/tensor_network_viz/_interaction/controller.py
|
|
74
|
+
src/tensor_network_viz/_interaction/scheme.py
|
|
75
|
+
src/tensor_network_viz/_interaction/state.py
|
|
66
76
|
src/tensor_network_viz/einsum_module/__init__.py
|
|
67
77
|
src/tensor_network_viz/einsum_module/_backend.py
|
|
68
78
|
src/tensor_network_viz/einsum_module/_equation.py
|
|
@@ -104,6 +114,7 @@ tests/test_graph_cache.py
|
|
|
104
114
|
tests/test_integration_einsum.py
|
|
105
115
|
tests/test_integration_tensorkrowch.py
|
|
106
116
|
tests/test_integration_tensornetwork.py
|
|
117
|
+
tests/test_interaction_state.py
|
|
107
118
|
tests/test_label_draw_metrics_perf.py
|
|
108
119
|
tests/test_label_format.py
|
|
109
120
|
tests/test_layout_core.py
|
|
@@ -13,6 +13,7 @@ from ..layout import NodePositions
|
|
|
13
13
|
from .constants import _CURVE_NEAR_PAIR_REF, _CURVE_OFFSET_FACTOR
|
|
14
14
|
from .edge_labels import _plot_contraction_index_captions
|
|
15
15
|
from .fonts_and_scale import _DrawScaleParams
|
|
16
|
+
from .label_descriptors import _TextLabelDescriptor
|
|
16
17
|
from .labels_misc import _contraction_hover_label_text
|
|
17
18
|
from .plotter import _PlotAdapter
|
|
18
19
|
from .scene_state import _RenderedEdgeGeometry
|
|
@@ -113,6 +114,7 @@ def _draw_contraction_edge_labels(
|
|
|
113
114
|
ax: Any,
|
|
114
115
|
scale: float,
|
|
115
116
|
zorder_label: float | None = None,
|
|
117
|
+
label_sink: list[_TextLabelDescriptor] | None = None,
|
|
116
118
|
) -> None:
|
|
117
119
|
hover_targets = getattr(plotter, "_hover_edge_targets", None)
|
|
118
120
|
if config.hover_labels and hover_targets is not None:
|
|
@@ -139,6 +141,7 @@ def _draw_contraction_edge_labels(
|
|
|
139
141
|
ax=ax,
|
|
140
142
|
scale=scale,
|
|
141
143
|
zorder_label=zorder_label,
|
|
144
|
+
label_sink=label_sink,
|
|
142
145
|
)
|
|
143
146
|
|
|
144
147
|
|
|
@@ -10,8 +10,12 @@ from .._label_format import format_tensor_node_label
|
|
|
10
10
|
from ..curves import _ellipse_points, _ellipse_points_3d, _require_self_endpoints
|
|
11
11
|
from ..graph import _EdgeData, _endpoint_index_caption, _GraphData
|
|
12
12
|
from ..layout import AxisDirections, NodePositions, _orthogonal_unit
|
|
13
|
-
from .constants import
|
|
13
|
+
from .constants import (
|
|
14
|
+
_EDGE_INDEX_LABEL_ALONG_FRAC,
|
|
15
|
+
_PHYS_DANGLING_2D_FRAC_FROM_TIP,
|
|
16
|
+
)
|
|
14
17
|
from .fonts_and_scale import _DrawScaleParams
|
|
18
|
+
from .label_descriptors import _TextLabelDescriptor
|
|
15
19
|
from .labels_misc import (
|
|
16
20
|
_curve_index_outside_disk,
|
|
17
21
|
_dangling_hover_label_text,
|
|
@@ -116,6 +120,7 @@ def _draw_dangling_edge_labels(
|
|
|
116
120
|
ax: Any,
|
|
117
121
|
scale: float,
|
|
118
122
|
zorder_label: float | None = None,
|
|
123
|
+
label_sink: list[_TextLabelDescriptor] | None = None,
|
|
119
124
|
) -> None:
|
|
120
125
|
if not edge.label and not config.hover_labels:
|
|
121
126
|
return
|
|
@@ -148,6 +153,11 @@ def _draw_dangling_edge_labels(
|
|
|
148
153
|
return
|
|
149
154
|
|
|
150
155
|
raw_label = edge.label
|
|
156
|
+
stub_segment = np.stack([np.asarray(start, dtype=float), np.asarray(end, dtype=float)], axis=0)
|
|
157
|
+
stub_length = _polyline_arc_length_total(stub_segment)
|
|
158
|
+
distance_from_tip = float(_PHYS_DANGLING_2D_FRAC_FROM_TIP) * stub_length
|
|
159
|
+
point, tangent = _point_tangent_along_polyline_from_end(stub_segment, distance_from_tip)
|
|
160
|
+
|
|
151
161
|
fontsize = _edge_index_fontsize_for_bond(
|
|
152
162
|
raw_label,
|
|
153
163
|
bond_start=start,
|
|
@@ -163,10 +173,6 @@ def _draw_dangling_edge_labels(
|
|
|
163
173
|
bbox_pad=p.index_bbox_pad,
|
|
164
174
|
zorder=zorder_label,
|
|
165
175
|
)
|
|
166
|
-
stub_segment = np.stack([np.asarray(start, dtype=float), np.asarray(end, dtype=float)], axis=0)
|
|
167
|
-
stub_length = _polyline_arc_length_total(stub_segment)
|
|
168
|
-
distance_from_tip = float(_PHYS_DANGLING_2D_FRAC_FROM_TIP) * stub_length
|
|
169
|
-
point, tangent = _point_tangent_along_polyline_from_end(stub_segment, distance_from_tip)
|
|
170
176
|
if dimensions == 2:
|
|
171
177
|
start_2d = np.asarray(start[:2], dtype=float)
|
|
172
178
|
end_2d = np.asarray(end[:2], dtype=float)
|
|
@@ -200,11 +206,18 @@ def _draw_dangling_edge_labels(
|
|
|
200
206
|
scale=scale,
|
|
201
207
|
fontsize_pt=float(fontsize),
|
|
202
208
|
)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
209
|
+
formatted = format_tensor_node_label(raw_label)
|
|
210
|
+
kwargs = {**text_kwargs, **align_kwargs}
|
|
211
|
+
if label_sink is not None:
|
|
212
|
+
label_sink.append(
|
|
213
|
+
_TextLabelDescriptor(
|
|
214
|
+
position=np.asarray(label_pos, dtype=float).copy(),
|
|
215
|
+
text=formatted,
|
|
216
|
+
kwargs=dict(kwargs),
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
return
|
|
220
|
+
plotter.plot_text(label_pos, formatted, **kwargs)
|
|
208
221
|
|
|
209
222
|
|
|
210
223
|
def _draw_self_loop_edge(
|
|
@@ -299,6 +312,7 @@ def _draw_self_loop_edge_labels(
|
|
|
299
312
|
ax: Any,
|
|
300
313
|
scale: float,
|
|
301
314
|
zorder_label: float | None = None,
|
|
315
|
+
label_sink: list[_TextLabelDescriptor] | None = None,
|
|
302
316
|
) -> None:
|
|
303
317
|
hover_targets = getattr(plotter, "_hover_edge_targets", None)
|
|
304
318
|
if config.hover_labels and hover_targets is not None:
|
|
@@ -388,11 +402,22 @@ def _draw_self_loop_edge_labels(
|
|
|
388
402
|
dimensions=dimensions,
|
|
389
403
|
),
|
|
390
404
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
405
|
+
position_a = np.asarray(q_a, dtype=float) + offset_a
|
|
406
|
+
formatted_a = format_tensor_node_label(caption_a)
|
|
407
|
+
if label_sink is not None:
|
|
408
|
+
label_sink.append(
|
|
409
|
+
_TextLabelDescriptor(
|
|
410
|
+
position=np.asarray(position_a, dtype=float).copy(),
|
|
411
|
+
text=formatted_a,
|
|
412
|
+
kwargs=dict(text_kwargs_a),
|
|
413
|
+
)
|
|
414
|
+
)
|
|
415
|
+
else:
|
|
416
|
+
plotter.plot_text(
|
|
417
|
+
position_a,
|
|
418
|
+
formatted_a,
|
|
419
|
+
**text_kwargs_a,
|
|
420
|
+
)
|
|
396
421
|
if caption_b:
|
|
397
422
|
offset_b = (
|
|
398
423
|
-direction_unit
|
|
@@ -430,9 +455,20 @@ def _draw_self_loop_edge_labels(
|
|
|
430
455
|
dimensions=dimensions,
|
|
431
456
|
),
|
|
432
457
|
}
|
|
458
|
+
formatted_b = format_tensor_node_label(caption_b)
|
|
459
|
+
position_b = np.asarray(q_b, dtype=float) + offset_b
|
|
460
|
+
if label_sink is not None:
|
|
461
|
+
label_sink.append(
|
|
462
|
+
_TextLabelDescriptor(
|
|
463
|
+
position=np.asarray(position_b, dtype=float).copy(),
|
|
464
|
+
text=formatted_b,
|
|
465
|
+
kwargs=dict(text_kwargs_b),
|
|
466
|
+
)
|
|
467
|
+
)
|
|
468
|
+
return
|
|
433
469
|
plotter.plot_text(
|
|
434
|
-
|
|
435
|
-
|
|
470
|
+
position_b,
|
|
471
|
+
formatted_b,
|
|
436
472
|
**text_kwargs_b,
|
|
437
473
|
)
|
|
438
474
|
|
|
@@ -16,6 +16,7 @@ from ..graph import (
|
|
|
16
16
|
)
|
|
17
17
|
from ..layout import NodePositions
|
|
18
18
|
from .fonts_and_scale import _DrawScaleParams
|
|
19
|
+
from .label_descriptors import _TextLabelDescriptor
|
|
19
20
|
from .labels_misc import _edge_index_text_kwargs
|
|
20
21
|
from .plotter import _PlotAdapter
|
|
21
22
|
from .viewport_geometry import (
|
|
@@ -46,6 +47,7 @@ def _plot_contraction_index_captions(
|
|
|
46
47
|
ax: Any,
|
|
47
48
|
scale: float,
|
|
48
49
|
zorder_label: float | None = None,
|
|
50
|
+
label_sink: list[_TextLabelDescriptor] | None = None,
|
|
49
51
|
) -> None:
|
|
50
52
|
ep_l, ep_r = _require_contraction_endpoints(edge)
|
|
51
53
|
cap_l: str | None = _endpoint_index_caption(ep_l, edge, graph)
|
|
@@ -129,11 +131,18 @@ def _plot_contraction_index_captions(
|
|
|
129
131
|
scale=scale,
|
|
130
132
|
fontsize_pt=float(fontsize),
|
|
131
133
|
)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
formatted = format_tensor_node_label(cap)
|
|
135
|
+
kwargs = {**text_kwargs, **align_kwargs}
|
|
136
|
+
if label_sink is not None:
|
|
137
|
+
label_sink.append(
|
|
138
|
+
_TextLabelDescriptor(
|
|
139
|
+
position=np.asarray(position, dtype=float).copy(),
|
|
140
|
+
text=formatted,
|
|
141
|
+
kwargs=dict(kwargs),
|
|
142
|
+
)
|
|
143
|
+
)
|
|
144
|
+
continue
|
|
145
|
+
plotter.plot_text(position, formatted, **kwargs)
|
|
137
146
|
|
|
138
147
|
|
|
139
148
|
__all__ = ["_plot_contraction_index_captions"]
|
|
@@ -7,7 +7,13 @@ from ...config import PlotConfig
|
|
|
7
7
|
from ..contractions import _ContractionGroups
|
|
8
8
|
from ..graph import _EdgeData, _GraphData
|
|
9
9
|
from ..layout import AxisDirections, NodePositions
|
|
10
|
-
from .constants import
|
|
10
|
+
from .constants import (
|
|
11
|
+
_ZORDER_LAYER_BASE,
|
|
12
|
+
_ZORDER_LAYER_BOND,
|
|
13
|
+
_ZORDER_LAYER_DANGLING,
|
|
14
|
+
_ZORDER_LAYER_EDGE_INDEX,
|
|
15
|
+
_ZORDER_LAYER_STRIDE,
|
|
16
|
+
)
|
|
11
17
|
from .contraction_edges import _draw_contraction_edge
|
|
12
18
|
from .dangling_self_edges import _draw_dangling_edge, _draw_self_loop_edge
|
|
13
19
|
from .fonts_and_scale import _DrawScaleParams
|