scatter3d-anywidget 0.1.2__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.
@@ -0,0 +1,48 @@
1
+ import marimo
2
+
3
+ __generated_with = "0.19.2"
4
+ app = marimo.App(width="medium")
5
+
6
+
7
+ @app.cell
8
+ def _():
9
+ import random
10
+ from scatter3d import Scatter3dWidget, Category, LabelListErrorResponse
11
+ import marimo
12
+ import numpy as np
13
+ import pandas
14
+
15
+ num_points = 100
16
+
17
+ point_ids = [f"id_{i}" for i in range(1, num_points + 1)]
18
+ points = np.random.randn(num_points, 3)
19
+ species_list = ["species1", "species2", "species3"]
20
+ species = random.choices(species_list, k=num_points)
21
+ species = Category(pandas.Series(species, name="species"))
22
+
23
+ w = Scatter3dWidget(xyz=points, category=species, point_ids=point_ids)
24
+ ui = marimo.ui.anywidget(w)
25
+ ui
26
+ return species, ui, w
27
+
28
+
29
+ @app.cell
30
+ def _(species, ui, w):
31
+ ui.lasso_result_t
32
+ print(species.values.value_counts())
33
+ print(species.num_unassigned)
34
+ print(species.values)
35
+ print(w.point_ids)
36
+ return
37
+
38
+
39
+ @app.cell
40
+ def _(w):
41
+ import inspect
42
+ print(type(w))
43
+ print(inspect.getsource(type(w)._on_lasso_request_t))
44
+ return
45
+
46
+
47
+ if __name__ == "__main__":
48
+ app.run()
@@ -0,0 +1,145 @@
1
+ Metadata-Version: 2.3
2
+ Name: scatter3d-anywidget
3
+ Version: 0.1.2
4
+ Summary: 3D scatter widget with lasso selection
5
+ License: MIT
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Topic :: Scientific/Engineering :: Visualization
12
+ Requires-Dist: anywidget>=0.9.21
13
+ Requires-Dist: narwhals>=2.14.0
14
+ Requires-Dist: numpy>=2.3.5
15
+ Requires-Python: >=3.13
16
+ Project-URL: Homepage, https://github.com/JoseBlanca/any_scatter3d
17
+ Project-URL: Issues, https://github.com/JoseBlanca/any_scatter3d/issues
18
+ Project-URL: Repository, https://github.com/JoseBlanca/any_scatter3d
19
+ Description-Content-Type: text/markdown
20
+
21
+ # scatter3d-anywidget
22
+
23
+ **Interactive 3D scatter plots for Python notebooks, with lasso-based selection and categorical annotation.**
24
+
25
+ `scatter3d-anywidget` provides a high-performance, WebGL-based 3D scatter plot widget built on top of **[anywidget](https://anywidget.dev/)**.
26
+ It is designed for exploratory data analysis workflows where users need to **interactively select, assign, and modify categories** on point clouds.
27
+
28
+ ![scatter3d widget example](scatter_widget_example.png)
29
+
30
+ ## Features
31
+
32
+ * **3D scatter visualization** (WebGL / Three.js) (up to tens of thousands of points)
33
+ * **Lasso selection** with *add* and *remove* operations
34
+ * **Categorical annotation** backed by pandas or Polars Series thanks to [narwhals](https://narwhals-dev.github.io/narwhals/)
35
+ * **Bidirectional sync** between Python state and frontend
36
+ * Designed for **anywidget**, works well with **marimo** and Jupyter
37
+
38
+ ## Project status
39
+
40
+ ⚠️ **Alpha status**, this is alpha software that we are using in our research.
41
+
42
+ This project is under active development.
43
+ APIs, traitlets, and frontend behavior may change without notice.
44
+
45
+ Contributions and feedback are welcome.
46
+
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install scatter3d-anywidget
52
+ ```
53
+
54
+ ![License](https://img.shields.io/badge/license-MIT-blue.svg)
55
+
56
+ ## Requirements
57
+
58
+ - Python ≥ 3.13
59
+ - Jupyter or marimo
60
+ - WebGL-capable browser
61
+
62
+ ## Basic usage
63
+
64
+ Below is a minimal example showing how to:
65
+
66
+ * Create a 3D scatter plot
67
+ * Attach a categorical variable
68
+ * Modify category labels programmatically
69
+ * Inspect lasso selections from Python
70
+
71
+ ```python
72
+ import random
73
+ import numpy as np
74
+ import pandas as pd
75
+ import marimo
76
+
77
+ from scatter3d import Scatter3dWidget, Category, LabelListErrorResponse
78
+
79
+ num_points = 10_000
80
+
81
+ # Generate random 3D points
82
+ points = np.random.randn(num_points, 3)
83
+
84
+ # Create a categorical variable
85
+ species_list = ["species1", "species2", "species3"]
86
+ species = random.choices(species_list, k=num_points)
87
+ species = Category(pd.Series(species, name="species"))
88
+
89
+ # Create the widget
90
+ w = Scatter3dWidget(xyz=points, category=species)
91
+ w.point_size = 0.15
92
+
93
+ # Modify allowed labels
94
+ species.set_label_list(
95
+ ["species1"],
96
+ on_missing_labels=LabelListErrorResponse.SET_MISSING,
97
+ )
98
+
99
+ species.set_label_list(["species1", "species4"])
100
+
101
+ # Display in marimo / Jupyter
102
+ ui = marimo.ui.anywidget(w)
103
+ ui
104
+ ```
105
+
106
+ After interacting with the plot (e.g. lasso selection), you can inspect results from Python:
107
+
108
+ ```python
109
+ # Result of the last lasso operation
110
+ ui.lasso_result_t
111
+
112
+ # Category statistics
113
+ print(species.values.value_counts())
114
+ print(species.num_unassigned)
115
+ ```
116
+
117
+ ## Interactive operation
118
+
119
+ The widget is fully interactive and designed for exploratory annotation workflows. Users can rotate, pan, and zoom the 3D point cloud directly with the mouse. A lasso tool allows drawing a free-form polygon in screen space to select subsets of points. Once a lasso selection is completed, the selection can be applied to the active category using add or remove operations, updating both the visual state and the underlying Python Category object. All interactions are bidirectionally synchronized: changes made via the UI are immediately reflected in Python, and programmatic updates from Python are propagated back to the frontend. This enables tight interactive loops where visual inspection, manual selection, and scripted analysis coexist seamlessly.
120
+
121
+ ## Concepts
122
+
123
+ ### `Scatter3dWidget`
124
+
125
+ The main widget. It owns the point cloud, rendering state, and interaction logic.
126
+
127
+ ### `Category`
128
+
129
+ A wrapper around a categorical vector (pandas or Polars Series) that:
130
+
131
+ * Encodes categories efficiently
132
+ * Tracks unassigned values
133
+ * `Category` objects are **stateful**: updating them updates the widget, and vice versa.
134
+
135
+ ### Lasso interaction
136
+
137
+ The lasso tool allows:
138
+
139
+ * Selecting points in screen space
140
+ * Adding or removing points from a category
141
+ * Reading back selection results in Python
142
+
143
+ ## License
144
+
145
+ MIT
@@ -0,0 +1,8 @@
1
+ scatter3d/__init__.py,sha256=nVTx6roiwzTe5lpGoMHw7pDZovHdhbxcVOgg4J3trT4,142
2
+ scatter3d/scatter3d.py,sha256=HPAjrZWAEAaOPBuQnN1Lh2PzFyPajNPLrHi60EM5_Yg,36334
3
+ scatter3d/static/scatter3d.js,sha256=TpMbhUKtVOHg8Aydh00Ti0N8iTs90TeAsMSxLhvip-0,889726
4
+ scatter3d/static/scatter3d.js.map,sha256=gd3ISXRZrHl_rQ9W5AZqyGU12T-dggRkFnytpp-ZrpQ,3013931
5
+ scatter3d/widget_test.py,sha256=sWxewIrhcNwssyd6TJyG1ulXciPX7D0QRLxVxml6VhQ,1060
6
+ scatter3d_anywidget-0.1.2.dist-info/WHEEL,sha256=eycQt0QpYmJMLKpE3X9iDk8R04v2ZF0x82ogq-zP6bQ,79
7
+ scatter3d_anywidget-0.1.2.dist-info/METADATA,sha256=0bURpON3pHQkuhAPm6JpjgM7skv6i25-yM5s3FsS-no,4697
8
+ scatter3d_anywidget-0.1.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.24
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any