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.
Files changed (142) hide show
  1. {tensor_network_visualization-1.5.1/src/tensor_network_visualization.egg-info → tensor_network_visualization-1.5.2}/PKG-INFO +14 -6
  2. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/README.md +13 -5
  3. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/pyproject.toml +5 -3
  4. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2/src/tensor_network_visualization.egg-info}/PKG-INFO +14 -6
  5. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_visualization.egg-info/SOURCES.txt +11 -0
  6. tensor_network_visualization-1.5.2/src/tensor_network_viz/_core/_draw_common.py +9 -0
  7. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/contraction_edges.py +3 -0
  8. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/dangling_self_edges.py +53 -17
  9. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/edge_labels.py +14 -5
  10. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/edge_orchestration.py +7 -1
  11. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/fonts_and_scale.py +184 -182
  12. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/graph_pipeline.py +23 -56
  13. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/hover.py +22 -11
  14. tensor_network_visualization-1.5.2/src/tensor_network_viz/_core/draw/label_descriptors.py +56 -0
  15. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/labels_misc.py +158 -154
  16. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/plotter.py +312 -304
  17. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/render_prep.py +74 -11
  18. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/scene_state.py +5 -0
  19. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/tensors.py +30 -6
  20. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/viewport_geometry.py +19 -1
  21. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/graph.py +5 -0
  22. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/graph_cache.py +60 -0
  23. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/direction_common.py +528 -477
  24. tensor_network_visualization-1.5.2/src/tensor_network_viz/_core/layout/free_directions_2d.py +920 -0
  25. tensor_network_visualization-1.5.2/src/tensor_network_viz/_core/layout/free_directions_3d.py +495 -0
  26. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/geometry.py +21 -0
  27. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/renderer.py +11 -2
  28. tensor_network_visualization-1.5.2/src/tensor_network_viz/_input_inspection.py +157 -0
  29. tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/__init__.py +3 -0
  30. tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/bridge.py +164 -0
  31. tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/controller.py +662 -0
  32. tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/scheme.py +245 -0
  33. tensor_network_visualization-1.5.2/src/tensor_network_viz/_interaction/state.py +88 -0
  34. tensor_network_visualization-1.5.2/src/tensor_network_viz/_interactive_scene.py +493 -0
  35. tensor_network_visualization-1.5.2/src/tensor_network_viz/_matplotlib_state.py +55 -0
  36. 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
  37. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_tensor_elements_data.py +190 -88
  38. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_tensor_elements_payloads.py +99 -14
  39. tensor_network_visualization-1.5.2/src/tensor_network_viz/_ui_utils.py +69 -0
  40. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/config.py +7 -4
  41. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/contraction_viewer.py +152 -49
  42. tensor_network_visualization-1.5.2/src/tensor_network_viz/einsum_module/contraction_cost.py +150 -0
  43. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/graph.py +22 -7
  44. tensor_network_visualization-1.5.2/src/tensor_network_viz/interactive_viewer.py +7 -0
  45. tensor_network_visualization-1.5.2/src/tensor_network_viz/tensor_elements.py +99 -0
  46. tensor_network_visualization-1.5.2/src/tensor_network_viz/tensor_elements_config.py +60 -0
  47. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/viewer.py +10 -80
  48. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_ci_workflow.py +9 -2
  49. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_contraction_cost.py +105 -6
  50. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_contraction_viewer.py +38 -4
  51. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_demo_cli_scheme.py +17 -1
  52. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_draw_performance.py +3 -0
  53. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_einsum_backend.py +41 -1
  54. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_engineering_baseline.py +54 -0
  55. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_examples.py +180 -0
  56. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_graph_cache.py +45 -0
  57. tensor_network_visualization-1.5.2/tests/test_interaction_state.py +165 -0
  58. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_label_draw_metrics_perf.py +3 -0
  59. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_layout_core.py +591 -9
  60. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_node_degrees_perf.py +2 -0
  61. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_plotting.py +433 -8
  62. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_public_api.py +1 -0
  63. tensor_network_visualization-1.5.2/tests/test_show_tensor_network_throughput.py +172 -0
  64. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_tensor_elements.py +476 -6
  65. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_tensor_elements_perf.py +2 -0
  66. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_verify_script.py +1 -1
  67. tensor_network_visualization-1.5.1/src/tensor_network_viz/_core/_draw_common.py +0 -6
  68. tensor_network_visualization-1.5.1/src/tensor_network_viz/_core/layout/free_directions_2d.py +0 -493
  69. tensor_network_visualization-1.5.1/src/tensor_network_viz/_core/layout/free_directions_3d.py +0 -250
  70. tensor_network_visualization-1.5.1/src/tensor_network_viz/_ui_utils.py +0 -33
  71. tensor_network_visualization-1.5.1/src/tensor_network_viz/einsum_module/contraction_cost.py +0 -79
  72. tensor_network_visualization-1.5.1/src/tensor_network_viz/interactive_viewer.py +0 -572
  73. tensor_network_visualization-1.5.1/src/tensor_network_viz/tensor_elements_config.py +0 -34
  74. tensor_network_visualization-1.5.1/tests/test_show_tensor_network_throughput.py +0 -57
  75. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/LICENSE +0 -0
  76. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/setup.cfg +0 -0
  77. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_visualization.egg-info/dependency_links.txt +0 -0
  78. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_visualization.egg-info/requires.txt +0 -0
  79. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_visualization.egg-info/top_level.txt +0 -0
  80. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/__init__.py +0 -0
  81. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/__init__.py +0 -0
  82. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/_label_format.py +0 -0
  83. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/_nodes_edges_common.py +0 -0
  84. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/axis_directions.py +0 -0
  85. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/contractions.py +0 -0
  86. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/curves.py +0 -0
  87. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/__init__.py +0 -0
  88. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/constants.py +0 -0
  89. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/contraction_scheme.py +0 -0
  90. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/disk_metrics.py +0 -0
  91. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/edges.py +0 -0
  92. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/pick_distance.py +0 -0
  93. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/draw/vectors.py +0 -0
  94. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/graph_utils.py +0 -0
  95. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/__init__.py +0 -0
  96. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/body.py +0 -0
  97. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/force_directed.py +0 -0
  98. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/parameters.py +0 -0
  99. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/positions.py +0 -0
  100. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout/types.py +0 -0
  101. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_core/layout_structure.py +0 -0
  102. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_engine_specs.py +0 -0
  103. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_registry.py +0 -0
  104. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_tensor_elements_support.py +0 -0
  105. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/_typing.py +0 -0
  106. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/__init__.py +0 -0
  107. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/_backend.py +0 -0
  108. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/_equation.py +0 -0
  109. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/_trace_state.py +0 -0
  110. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/_trace_types.py +0 -0
  111. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/renderer.py +0 -0
  112. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/einsum_module/trace.py +0 -0
  113. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/py.typed +0 -0
  114. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/quimb/__init__.py +0 -0
  115. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/quimb/graph.py +0 -0
  116. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/quimb/renderer.py +0 -0
  117. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tenpy/__init__.py +0 -0
  118. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tenpy/explicit.py +0 -0
  119. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tenpy/graph.py +0 -0
  120. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tenpy/renderer.py +0 -0
  121. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensorkrowch/__init__.py +0 -0
  122. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensorkrowch/graph.py +0 -0
  123. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensorkrowch/renderer.py +0 -0
  124. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensornetwork/__init__.py +0 -0
  125. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensornetwork/graph.py +0 -0
  126. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/src/tensor_network_viz/tensornetwork/renderer.py +0 -0
  127. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_contraction_groups_once.py +0 -0
  128. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_contraction_scheme.py +0 -0
  129. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_edge_index_label_2d.py +0 -0
  130. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_edge_index_label_3d.py +0 -0
  131. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_einsum_autotrace.py +0 -0
  132. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_engine_detection.py +0 -0
  133. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_examples_structure.py +0 -0
  134. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_integration_einsum.py +0 -0
  135. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_integration_tensorkrowch.py +0 -0
  136. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_integration_tensornetwork.py +0 -0
  137. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_label_format.py +0 -0
  138. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_lazy_imports.py +0 -0
  139. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_packaging_metadata.py +0 -0
  140. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_quimb_backend.py +0 -0
  141. {tensor_network_visualization-1.5.1 → tensor_network_visualization-1.5.2}/tests/test_render_performance_controls.py +0 -0
  142. {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.1
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 `diagnostic` (`sign`,
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="sign"`, or `mode="signed_value"` directly in
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 cost tooltip on scheme regions. |
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 `diagnostic` (`sign`,
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="sign"`, or `mode="signed_value"` directly in
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 cost tooltip on scheme regions. |
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.1"
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.1
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 `diagnostic` (`sign`,
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="sign"`, or `mode="signed_value"` directly in
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 cost tooltip on scheme regions. |
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
@@ -0,0 +1,9 @@
1
+ """Shared scale and style parameters for 2D and 3D drawing."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from . import draw as _draw
6
+
7
+ __all__ = _draw.__all__
8
+
9
+ globals().update({name: getattr(_draw, name) for name in __all__})
@@ -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
- plotter.plot_text(
204
- label_pos,
205
- format_tensor_node_label(raw_label),
206
- **{**text_kwargs, **align_kwargs},
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
- plotter.plot_text(
392
- np.asarray(q_a, dtype=float) + offset_a,
393
- format_tensor_node_label(caption_a),
394
- **text_kwargs_a,
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
- np.asarray(q_b, dtype=float) + offset_b,
435
- format_tensor_node_label(caption_b),
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
- plotter.plot_text(
133
- position,
134
- format_tensor_node_label(cap),
135
- **{**text_kwargs, **align_kwargs},
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