{"id":43991610,"url":"https://github.com/grafeodb/anywidget-vector","last_synced_at":"2026-03-16T01:49:08.719Z","repository":{"id":336315095,"uuid":"1148375881","full_name":"GrafeoDB/anywidget-vector","owner":"GrafeoDB","description":"Interactive 3D vector visualization for Python notebooks.","archived":false,"fork":false,"pushed_at":"2026-02-04T08:01:50.000Z","size":336,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-04T09:14:45.455Z","etag":null,"topics":["anywidget","grafeo","grafeodb","marimo","vector-database"],"latest_commit_sha":null,"homepage":"https://grafeo.dev/ecosystem/anywidget-vector/ ","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GrafeoDB.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-02T22:26:38.000Z","updated_at":"2026-02-04T08:01:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/GrafeoDB/anywidget-vector","commit_stats":null,"previous_names":["grafeodb/anywidget-vector"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/GrafeoDB/anywidget-vector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrafeoDB%2Fanywidget-vector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrafeoDB%2Fanywidget-vector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrafeoDB%2Fanywidget-vector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrafeoDB%2Fanywidget-vector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GrafeoDB","download_url":"https://codeload.github.com/GrafeoDB/anywidget-vector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GrafeoDB%2Fanywidget-vector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29193089,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T07:37:03.739Z","status":"ssl_error","status_checked_at":"2026-02-07T07:37:03.029Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anywidget","grafeo","grafeodb","marimo","vector-database"],"created_at":"2026-02-07T11:02:53.339Z","updated_at":"2026-03-16T01:49:08.707Z","avatar_url":"https://github.com/GrafeoDB.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# anywidget-vector\n\nInteractive 3D vector visualization for Python notebooks.\n\nWorks with Marimo, Jupyter, VS Code, Colab, anywhere [anywidget](https://anywidget.dev/) runs.\n\n![anywidget-vector demo](assets/demo.png)\n\n## Features\n\n- **Universal**: One widget, every notebook environment\n- **6D Visualization**: X, Y, Z position + Color, Shape, Size encoding\n- **Backend-agnostic**: NumPy, pandas, Qdrant, Chroma, Pinecone, Weaviate, LanceDB, or raw dicts\n- **Interactive**: Orbit, pan, zoom, click, hover, box select\n- **Customizable**: Color scales, shapes, sizes, themes\n- **Performant**: Instanced rendering for large point clouds\n\n## Installation\n\n```bash\nuv add anywidget-vector\n```\n\n## Quick Start\n\n```python\nfrom anywidget_vector import VectorSpace\n\nwidget = VectorSpace(points=[\n    {\"id\": \"a\", \"x\": 0.5, \"y\": 0.3, \"z\": 0.8, \"label\": \"Point A\", \"cluster\": 0},\n    {\"id\": \"b\", \"x\": -0.2, \"y\": 0.7, \"z\": 0.1, \"label\": \"Point B\", \"cluster\": 1},\n    {\"id\": \"c\", \"x\": 0.1, \"y\": -0.4, \"z\": 0.6, \"label\": \"Point C\", \"cluster\": 0},\n])\n\nwidget\n```\n\n## Data Sources\n\n### Dictionary\n\n```python\nwidget = VectorSpace.from_dict({\n    \"points\": [\n        {\"id\": \"a\", \"x\": 0, \"y\": 0, \"z\": 0},\n        {\"id\": \"b\", \"x\": 1, \"y\": 1, \"z\": 1},\n    ]\n})\n```\n\n### NumPy Arrays\n\n```python\nimport numpy as np\n\npositions = np.random.randn(100, 3)\nwidget = VectorSpace.from_numpy(positions)\n```\n\n### pandas DataFrame\n\n```python\nimport pandas as pd\n\ndf = pd.DataFrame({\n    \"x\": [0.1, 0.5, 0.9],\n    \"y\": [0.2, 0.6, 0.3],\n    \"z\": [0.3, 0.1, 0.7],\n    \"cluster\": [\"A\", \"B\", \"A\"],\n    \"size\": [0.5, 1.0, 0.8],\n})\n\nwidget = VectorSpace.from_dataframe(\n    df,\n    color_col=\"cluster\",\n    size_col=\"size\",\n)\n```\n\n### UMAP / t-SNE / PCA\n\n```python\nimport umap\n\nembedding = umap.UMAP(n_components=3).fit_transform(high_dim_data)\nwidget = VectorSpace.from_umap(embedding, labels=labels)\n```\n\n### Qdrant\n\n```python\nfrom qdrant_client import QdrantClient\n\nclient = QdrantClient(\"localhost\", port=6333)\nwidget = VectorSpace.from_qdrant(client, \"my_collection\", limit=5000)\n```\n\n### ChromaDB\n\n```python\nimport chromadb\n\nclient = chromadb.Client()\ncollection = client.get_collection(\"embeddings\")\nwidget = VectorSpace.from_chroma(collection)\n```\n\n### Pinecone\n\n```python\nfrom pinecone import Pinecone\n\npc = Pinecone(api_key=\"...\")\nindex = pc.Index(\"my-index\")\nwidget = VectorSpace.from_pinecone(index, limit=5000)\n```\n\n### Weaviate\n\n```python\nimport weaviate\n\nclient = weaviate.Client(\"http://localhost:8080\")\nwidget = VectorSpace.from_weaviate(client, \"Article\", limit=5000)\n```\n\n### LanceDB\n\n```python\nimport lancedb\n\ndb = lancedb.connect(\"~/.lancedb\")\ntable = db.open_table(\"vectors\")\nwidget = VectorSpace.from_lancedb(table, limit=5000)\n```\n\n## Visual Encoding\n\n### 6 Dimensions\n\n| Dimension | Visual Channel | Example |\n|-----------|---------------|---------|\n| X | Horizontal position | `x` coordinate |\n| Y | Vertical position | `y` coordinate |\n| Z | Depth position | `z` coordinate |\n| Color | Hue/gradient | Cluster, score |\n| Shape | Geometry | Category, type |\n| Size | Scale | Importance, count |\n\n### Color Scales\n\n```python\nwidget = VectorSpace(\n    points=data,\n    color_field=\"score\",           # Field to map\n    color_scale=\"viridis\",         # Scale: viridis, plasma, inferno, magma, cividis, turbo\n    color_domain=[0, 100],         # Optional: explicit range\n)\n```\n\n### Shapes\n\n```python\nwidget = VectorSpace(\n    points=data,\n    shape_field=\"category\",\n    shape_map={\n        \"type_a\": \"sphere\",        # Available: sphere, cube, cone,\n        \"type_b\": \"cube\",          #            tetrahedron, octahedron, cylinder\n        \"type_c\": \"cone\",\n    }\n)\n```\n\n### Size\n\n```python\nwidget = VectorSpace(\n    points=data,\n    size_field=\"importance\",\n    size_range=[0.02, 0.15],       # Min/max point size\n)\n```\n\n## Interactivity\n\n### Events\n\n```python\nwidget = VectorSpace(points=data)\n\n@widget.on_click\ndef handle_click(point_id, point_data):\n    print(f\"Clicked: {point_id}\")\n\n@widget.on_hover\ndef handle_hover(point_id, point_data):\n    if point_id:\n        print(f\"Hovering: {point_id}\")\n\n@widget.on_selection\ndef handle_selection(point_ids, points_data):\n    print(f\"Selected {len(point_ids)} points\")\n```\n\n### Selection\n\n```python\nwidget.selected_points              # Current selection\nwidget.select([\"a\", \"b\"])           # Select points\nwidget.clear_selection()            # Clear\nwidget.selection_mode = \"box\"       # Switch to box-select mode\n```\n\n### Camera\n\n```python\nwidget.camera_position              # Get position [x, y, z]\nwidget.camera_target                # Get target [x, y, z]\nwidget.reset_camera()               # Reset to default\nwidget.focus_on([\"a\", \"b\"])         # Focus on specific points\n```\n\n## Distance Metrics\n\nCompute distances and visualize similarity relationships between points.\n\n### Supported Metrics\n\n| Metric | Description |\n|--------|-------------|\n| `euclidean` | Straight-line distance (L2 norm) |\n| `cosine` | Angle-based distance (1 - cosine similarity) |\n| `manhattan` | Sum of absolute differences (L1 norm) |\n| `dot_product` | Negative dot product (higher = closer) |\n\n### Color by Distance\n\n```python\nwidget.color_by_distance(\"point_a\")\nwidget.color_by_distance(\"point_a\", metric=\"cosine\")\n```\n\n### Find Neighbors\n\n```python\nneighbors = widget.find_neighbors(\"point_a\", k=5)\n# Returns: [(\"point_b\", 0.1), (\"point_c\", 0.2), ...]\n\nneighbors = widget.find_neighbors(\"point_a\", threshold=0.5)\n```\n\n### Show Connections\n\n```python\nwidget.show_neighbors(\"point_a\", k=5)\nwidget.show_neighbors(\"point_a\", threshold=0.3)\n\n# Manual connection settings\nwidget = VectorSpace(\n    points=data,\n    show_connections=True,\n    k_neighbors=3,\n    distance_metric=\"cosine\",\n    connection_color=\"#00ff00\",\n    connection_opacity=0.5,\n)\n```\n\n### Compute Distances\n\n```python\ndistances = widget.compute_distances(\"point_a\")\n# Returns: {\"point_b\": 0.1, \"point_c\": 0.5, ...}\n\n# Use high-dimensional vectors (not just x,y,z)\ndistances = widget.compute_distances(\n    \"point_a\",\n    metric=\"cosine\",\n    vector_field=\"embedding\"\n)\n```\n\n## Options\n\n```python\nwidget = VectorSpace(\n    points=data,\n    width=1000,\n    height=700,\n    background=\"#1a1a2e\",         # Dark theme default\n    show_axes=True,\n    show_grid=True,\n    axis_labels={\"x\": \"PC1\", \"y\": \"PC2\", \"z\": \"PC3\"},\n    show_tooltip=True,\n    tooltip_fields=[\"label\", \"x\", \"y\", \"z\", \"cluster\"],\n    selection_mode=\"click\",       # \"click\", \"multi\", or \"box\"\n    use_instancing=True,          # Performance: instanced rendering\n)\n```\n\n## Backends\n\nConfigure a backend for interactive querying:\n\n```python\nwidget.set_backend(\"chroma\", client=collection)\nwidget.set_backend(\"lancedb\", client=table)\nwidget.set_backend(\"grafeo\", client=db)\n```\n\n## Export\n\n```python\nwidget.to_json()                            # Points as JSON string\nwidget.to_html()                            # Self-contained HTML string\nwidget.to_html(title=\"My Vectors\")          # Custom title\nwidget.save_html(\"vectors.html\")            # Write HTML to file\n```\n\n## Environment Support\n\n| Environment | Supported |\n|-------------|-----------|\n| Marimo | Yes |\n| JupyterLab | Yes |\n| Jupyter Notebook | Yes |\n| VS Code | Yes |\n| Google Colab | Yes |\n| Databricks | Yes |\n\n## Related\n\n- [anywidget](https://anywidget.dev/), custom Jupyter widgets made easy\n- [anywidget-graph](https://github.com/GrafeoDB/anywidget-graph), graph visualization widget\n- [Three.js](https://threejs.org/), 3D JavaScript library\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafeodb%2Fanywidget-vector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrafeodb%2Fanywidget-vector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafeodb%2Fanywidget-vector/lists"}