scatter3d-anywidget 0.1.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.
@@ -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,125 @@
1
+ # scatter3d-anywidget
2
+
3
+ **Interactive 3D scatter plots for Python notebooks, with lasso-based selection and categorical annotation.**
4
+
5
+ `scatter3d-anywidget` provides a high-performance, WebGL-based 3D scatter plot widget built on top of **[anywidget](https://anywidget.dev/)**.
6
+ It is designed for exploratory data analysis workflows where users need to **interactively select, assign, and modify categories** on point clouds.
7
+
8
+ ![scatter3d widget example](scatter_widget_example.png)
9
+
10
+ ## Features
11
+
12
+ * **3D scatter visualization** (WebGL / Three.js) (up to tens of thousands of points)
13
+ * **Lasso selection** with *add* and *remove* operations
14
+ * **Categorical annotation** backed by pandas or Polars Series thanks to [narwhals](https://narwhals-dev.github.io/narwhals/)
15
+ * **Bidirectional sync** between Python state and frontend
16
+ * Designed for **anywidget**, works well with **marimo** and Jupyter
17
+
18
+ ## Project status
19
+
20
+ ⚠️ **Alpha status**, this is alpha software that we are using in our research.
21
+
22
+ This project is under active development.
23
+ APIs, traitlets, and frontend behavior may change without notice.
24
+
25
+ Contributions and feedback are welcome.
26
+
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install scatter3d-anywidget
32
+ ```
33
+
34
+ ![License](https://img.shields.io/badge/license-MIT-blue.svg)
35
+
36
+ ## Requirements
37
+
38
+ - Python ≥ 3.13
39
+ - Jupyter or marimo
40
+ - WebGL-capable browser
41
+
42
+ ## Basic usage
43
+
44
+ Below is a minimal example showing how to:
45
+
46
+ * Create a 3D scatter plot
47
+ * Attach a categorical variable
48
+ * Modify category labels programmatically
49
+ * Inspect lasso selections from Python
50
+
51
+ ```python
52
+ import random
53
+ import numpy as np
54
+ import pandas as pd
55
+ import marimo
56
+
57
+ from scatter3d import Scatter3dWidget, Category, LabelListErrorResponse
58
+
59
+ num_points = 10_000
60
+
61
+ # Generate random 3D points
62
+ points = np.random.randn(num_points, 3)
63
+
64
+ # Create a categorical variable
65
+ species_list = ["species1", "species2", "species3"]
66
+ species = random.choices(species_list, k=num_points)
67
+ species = Category(pd.Series(species, name="species"))
68
+
69
+ # Create the widget
70
+ w = Scatter3dWidget(xyz=points, category=species)
71
+ w.point_size = 0.15
72
+
73
+ # Modify allowed labels
74
+ species.set_label_list(
75
+ ["species1"],
76
+ on_missing_labels=LabelListErrorResponse.SET_MISSING,
77
+ )
78
+
79
+ species.set_label_list(["species1", "species4"])
80
+
81
+ # Display in marimo / Jupyter
82
+ ui = marimo.ui.anywidget(w)
83
+ ui
84
+ ```
85
+
86
+ After interacting with the plot (e.g. lasso selection), you can inspect results from Python:
87
+
88
+ ```python
89
+ # Result of the last lasso operation
90
+ ui.lasso_result_t
91
+
92
+ # Category statistics
93
+ print(species.values.value_counts())
94
+ print(species.num_unassigned)
95
+ ```
96
+
97
+ ## Interactive operation
98
+
99
+ 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.
100
+
101
+ ## Concepts
102
+
103
+ ### `Scatter3dWidget`
104
+
105
+ The main widget. It owns the point cloud, rendering state, and interaction logic.
106
+
107
+ ### `Category`
108
+
109
+ A wrapper around a categorical vector (pandas or Polars Series) that:
110
+
111
+ * Encodes categories efficiently
112
+ * Tracks unassigned values
113
+ * `Category` objects are **stateful**: updating them updates the widget, and vice versa.
114
+
115
+ ### Lasso interaction
116
+
117
+ The lasso tool allows:
118
+
119
+ * Selecting points in screen space
120
+ * Adding or removing points from a category
121
+ * Reading back selection results in Python
122
+
123
+ ## License
124
+
125
+ MIT
@@ -0,0 +1,31 @@
1
+ [project]
2
+ name = "scatter3d-anywidget"
3
+ version = "0.1.2"
4
+ description = "3D scatter widget with lasso selection"
5
+ readme = "README.md"
6
+ requires-python = ">=3.13"
7
+ license = { text = "MIT" }
8
+ dependencies = ["anywidget>=0.9.21", "narwhals>=2.14.0", "numpy>=2.3.5"]
9
+ classifiers = [
10
+ "Development Status :: 3 - Alpha",
11
+ "License :: OSI Approved :: MIT License",
12
+ "Programming Language :: Python :: 3",
13
+ "Programming Language :: Python :: 3.13",
14
+ "Intended Audience :: Science/Research",
15
+ "Topic :: Scientific/Engineering :: Visualization",
16
+ ]
17
+
18
+ [build-system]
19
+ requires = ["uv_build"]
20
+ build-backend = "uv_build"
21
+
22
+ [tool.uv.build-backend]
23
+ module-name = "scatter3d"
24
+
25
+ [dependency-groups]
26
+ dev = ["marimo>=0.18.4", "pandas>=2.3.3", "polars>=1.36.1", "pytest>=9.0.2"]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/JoseBlanca/any_scatter3d"
30
+ Repository = "https://github.com/JoseBlanca/any_scatter3d"
31
+ Issues = "https://github.com/JoseBlanca/any_scatter3d/issues"
@@ -0,0 +1,3 @@
1
+ from .scatter3d import Scatter3dWidget, Category, LabelListErrorResponse
2
+
3
+ __all__ = ["Scatter3dWidget", "Category", "LabelListErrorResponse"]