Skip to main content

deck.gl visualization library for marimo notebooks — interactive maps with 33 layer types

Project description

deckgl-marimo

PyPI Python CI License: MIT Open in molab

Interactive deck.gl visualization library for marimo notebooks. Render GPU-accelerated maps with 33 layer types, powered by MapLibre GL and anywidget.

Features

  • 10 deck.gl layer types — scatter plots, hexagonal bins, heatmaps, arcs, paths, polygons, GeoJSON, 3D columns, and more
  • Multi-layer maps — compose multiple layers on a single map
  • Standalone layers — display any layer directly without explicit map setup
  • Marimo-native reactivity — bind layer properties to sliders, dropdowns, and other widgets
  • Multiple data sources — pandas, polars, geopandas, DuckDB, GeoJSON dicts, and URLs
  • Authenticated data loading — pass HTTP headers, API keys, or credentials for remote data sources
  • Fully offline — all JavaScript bundled in the package, no CDN dependencies
  • Viewport readback — read the current map center, zoom, pitch, and bearing from Python
  • Click & hover events — inspect picked objects reactively in downstream cells

Installation

pip install deckgl-marimo
# or
uv add deckgl-marimo

Quickstart

Standalone layer

import marimo as mo
import deckgl_marimo as dgl

layer = dgl.ScatterplotLayer(
    data=df,
    get_position=["longitude", "latitude"],
    get_fill_color=[255, 140, 0],
    get_radius="population",
    radius_scale=10,
)

# Displays a map with one layer
widget = mo.ui.anywidget(layer)

Multi-layer map

m = dgl.Map(
    layers=[
        dgl.ScatterplotLayer(
            data=cities_df,
            get_position=["lon", "lat"],
            get_fill_color=[255, 140, 0],
            get_radius=5,
            radius_min_pixels=3,
        ),
        dgl.ArcLayer(
            data=flights_df,
            get_source_position=["src_lon", "src_lat"],
            get_target_position=["dst_lon", "dst_lat"],
            get_source_color=[0, 128, 255],
            get_target_color=[255, 0, 128],
        ),
    ],
    basemap="dark-matter",
    center=(-98.5, 39.8),
    zoom=4,
    pitch=45,
)

widget = mo.ui.anywidget(m)

Reactive controls

Important: Create the Map widget in a cell that does not depend on slider values. Update layers by assigning to map_widget.layer_specs in a separate cell. This keeps the map instance stable — sliders update layers via traitlet sync instead of recreating the entire map, which would cause tile reloads and a black screen flash.

# Cell 1 — sliders
radius = mo.ui.slider(200, 5000, value=1000, label="Radius")

# Cell 2 — create map widget (NO slider deps — stable, never re-executes)
map_widget = dgl.Map(basemap="dark-matter", center=(-1.4, 52.2), zoom=6, pitch=40)
widget = mo.ui.anywidget(map_widget)

# Cell 3 — display
widget

# Cell 4 — update layers reactively (re-executes when slider changes)
map_widget.layer_specs = [
    dgl.HexagonLayer(
        data=df,
        get_position=["lon", "lat"],
        radius=radius.value,
        extruded=True,
        elevation_scale=250,
    ).to_spec()
]

# Cell 5 — viewport readback
vp = widget.value.get("viewport", {})
mo.md(f"Zoom: {vp.get('zoom', 'N/A'):.1f}")

DuckDB integration

import duckdb

rel = duckdb.sql("SELECT lon, lat, value FROM 'data.parquet' WHERE value > 100")
layer = dgl.ScatterplotLayer(data=rel, get_position=["lon", "lat"])

Authenticated remote data

Any layer that loads data from a URL supports custom HTTP headers via fetch_headers, or full control over the fetch request via load_options.

# Bearer token
layer = dgl.GeoJsonLayer(
    data="https://secure-api.example.com/data.geojson",
    fetch_headers={"Authorization": "Bearer my-token"},
    get_fill_color=[0, 180, 230, 160],
)

# API key
layer = dgl.GeoJsonLayer(
    data="https://api.example.com/features",
    fetch_headers={"X-API-Key": "abc123"},
)

# Full fetch control (mTLS / CORS / custom options)
layer = dgl.GeoJsonLayer(
    data="https://internal.example.com/data.geojson",
    load_options={
        "fetch": {
            "credentials": "include",
            "mode": "cors",
            "headers": {"Authorization": "Bearer token"},
        }
    },
)

Both parameters are available on all layer types via BaseLayer. When fetch_headers and load_options both specify headers, the load_options headers take precedence.

Available layers

Fully tested (10)

Layer Use case
ScatterplotLayer Point data
GeoJsonLayer Polygons, lines, points from GeoJSON/GeoDataFrame
ArcLayer Origin-destination flows
PathLayer Routes, trajectories
PolygonLayer Filled regions
IconLayer Marker icons
TextLayer Labels
ColumnLayer 3D bars on map
HexagonLayer Hexagonal binning
HeatmapLayer Density visualization

Experimental (23)

All additional deck.gl layers are available as experimental stubs via deckgl_marimo.layers:

from deckgl_marimo.layers import TripsLayer, MVTLayer, H3HexagonLayer, ContourLayer
# ... and 19 more

Basemaps

dgl.Basemaps.list_available()
# ['bright', 'dark', 'dark-matter', 'embedded', 'liberty', 'light', 'none', 'osm', 'positron', 'voyager']

# Use any MapLibre-compatible style URL
dgl.Map(basemap="https://my-tileserver.example.com/style.json")

Troubleshooting

Content-Length errors in the marimo console

This is fixed in Marimo >= 0.22.0 please update to that.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

deckgl_marimo-0.3.0.tar.gz (838.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

deckgl_marimo-0.3.0-py3-none-any.whl (673.1 kB view details)

Uploaded Python 3

File details

Details for the file deckgl_marimo-0.3.0.tar.gz.

File metadata

  • Download URL: deckgl_marimo-0.3.0.tar.gz
  • Upload date:
  • Size: 838.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for deckgl_marimo-0.3.0.tar.gz
Algorithm Hash digest
SHA256 a0ea92ce595012556aaad9d20579314e72b538a48a9342b10cc0ed455cbfacbb
MD5 5a9b27fb115e28777b4200b987e968ab
BLAKE2b-256 baae01624f7a37e2c485c632c13118f2312705bd55b2b67762135333111c62dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for deckgl_marimo-0.3.0.tar.gz:

Publisher: publish.yml on kihaji/deckgl-marimo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deckgl_marimo-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: deckgl_marimo-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 673.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for deckgl_marimo-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e220beb6e0709dc25c3dda305662466b47cca2b7d5aa81497d7733830bb5e1e5
MD5 5fbd295f4e7710a2421a5c29b877b7d1
BLAKE2b-256 bfa445b74b3a54fea8adbd8d5261963589e7418e5a9e86c9b01f461e2fe53023

See more details on using hashes here.

Provenance

The following attestation bundles were made for deckgl_marimo-0.3.0-py3-none-any.whl:

Publisher: publish.yml on kihaji/deckgl-marimo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page