mrkeyoor.com_
Sat 08 Aug 20:58 UTC
PyPIDataupdated 08 Aug 2026

pydeck

pydeck is the Python binding for deck.gl, a WebGL visualization framework for large spatial data sets. Python code describes layers, views, tooltips, and camera state, then serializes that specification and its data to JavaScript for rendering in a browser or notebook. It is good at interactive maps and GPU-accelerated visual aggregation; it is not a server-side chart renderer or a GIS analysis engine.

Verdict

pydeck is a strong bridge from Python data frames to deck.gl when an interactive GPU map is the actual deliverable. Avoid it for headless rendering, GIS processing, or any workflow where browser and basemap dependencies are unacceptable.

API stability4/5The core Deck, Layer, ViewState, and data-accessor model has remained recognizable across pydeck releases, and it mirrors deck.gl rather than inventing a competing abstraction. Stability is limited by the frontend boundary: renamed deck.gl layer properties, JavaScript bundle changes, notebook display adapters, and provider behavior can affect output even when Python code still imports.
Docs4/5The pydeck documentation covers installation, layer construction, maps, tooltips, data transport, Jupyter use, settings, and examples, while the parent deck.gl site provides detailed pages for every layer property. The split is logical but makes users move between Python and JavaScript-oriented references, and some old links still use the deckgl.readthedocs.io hostname.
Maintenance5/5pydeck 0.9.3 was published on 2026-07-02, and the shared visgl/deck.gl repository had 14,362 stars, 474 open issues and PRs, and a push on 2026-08-08. The monorepo supplies active frontend development and many maintained layers, though Python-specific issues compete for attention with the much larger JavaScript project.
Ecosystem4/5It can display pandas-style records through the deck.gl layer catalog and appears in notebook and Streamlit workflows, with basemaps from common web providers. The ecosystem is broad on the rendering side but thin on Python-native plugins because most extension work happens in JavaScript; custom deck.gl layers require extra frontend packaging rather than a normal Python subclass.

Use it if

  • You need interactive point, arc, polygon, path, heatmap, hexagon, or trip visualizations that benefit from browser GPU rendering
  • Your data work happens in Python or a notebook but the output should behave like a deck.gl web map
  • You want to export a self-contained HTML visualization without building a React application
  • You already understand deck.gl layer properties and want a thin Python representation rather than a separate plotting grammar
Skip it if

Setup reality

pip install pydeck brings Jinja2 and NumPy and works for basic HTML output, but the visible result is JavaScript running in a WebGL-capable browser. Version 0.9.3 supports Python 3.8 and newer. Notebook support is where setup becomes uneven: the published jupyter extra requests ipywidgets 7.x, while many current notebook environments use widgets 8, so check the environment before blindly installing pydeck[jupyter]. The notebook, VS Code, Colab, and Streamlit each have different display plumbing, security policies, and persistence behavior. Basemap configuration is separate from overlay layers. Some map styles require Mapbox credentials, remote style URLs need network access, and a blank background can be a token, CSP, WebGL, or tile-provider problem rather than a layer bug. Accessor strings such as get_position are interpreted by deck.gl against serialized row fields; they are not Python expressions. Coordinates are normally longitude and latitude, while elevation and radius units vary by layer property. Large frames can make notebook messages and exported HTML enormous before the GPU gets involved, so aggregate or use URL/binary data paths when scale demands it. Tooltips use an HTML template and receive browser-side object fields, which means untrusted text should not be inserted as raw HTML. For repeatable exports, pin pydeck and test the generated file in the browser versions you support because the Python package ships or references a particular deck.gl frontend bundle.

Patterns

Render a basic scatterplot mapscatterplot-map

import pydeck as pdk

data = [{'lon': -122.4, 'lat': 37.78, 'count': 120}]
layer = pdk.Layer(
    'ScatterplotLayer', data,
    get_position='[lon, lat]', get_radius=100,
    get_fill_color=[30, 136, 229, 180], pickable=True,
)
deck = pdk.Deck(layers=[layer], initial_view_state=pdk.ViewState(
    longitude=-122.4, latitude=37.78, zoom=11
))
deck.show()

Coordinate accessors use longitude then latitude; get_position is evaluated by deck.gl against each serialized row.

Show row fields in a tooltipadd-tooltip

deck = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    tooltip={'html': '<b>{name}</b><br/>Count: {count}', 'style': {'color': 'white'}},
)

Tooltip placeholders refer to serialized object fields; do not put untrusted values into raw HTML without sanitizing them first.

Aggregate dense points into hexagonsaggregate-hexagons

hexes = pdk.Layer(
    'HexagonLayer', data,
    get_position='[lon, lat]',
    radius=250, elevation_scale=20,
    extruded=True, pickable=True,
)

Aggregation happens in the browser; sending every raw point can still dominate load time even when GPU drawing is quick.

Draw GeoJSON polygons and linesdraw-geojson

geo = pdk.Layer(
    'GeoJsonLayer', geojson,
    filled=True, stroked=True, pickable=True,
    get_fill_color=[0, 128, 255, 90],
    get_line_color=[20, 20, 20],
    line_width_min_pixels=1,
)

GeoJSON coordinates should be WGS84 longitude and latitude; pydeck does not reproject source geometry for you.

Connect origins and destinations with arcsconnect-points-with-arcs

arcs = pdk.Layer(
    'ArcLayer', trips,
    get_source_position='source',
    get_target_position='target',
    get_source_color=[0, 180, 255],
    get_target_color=[255, 80, 80],
    get_width=3, pickable=True,
)

Each source and target value must already be a two-number coordinate array in longitude, latitude order.

Render routes with PathLayerrender-paths

paths = pdk.Layer(
    'PathLayer', routes,
    get_path='path', get_color='color',
    width_scale=4, width_min_pixels=2,
    get_width=2, pickable=True,
)

A path is an array of coordinate arrays; simplify very detailed lines before serialization when browser payload is the bottleneck.

Create a weighted heatmapvisualize-heatmap

heat = pdk.Layer(
    'HeatmapLayer', points,
    get_position='[longitude, latitude]',
    get_weight='magnitude',
    radius_pixels=40,
)

radius_pixels is a screen-space smoothing radius, not meters, so the appearance changes as the camera zooms.

Render timestamped moving pathsanimate-trips

trips_layer = pdk.Layer(
    'TripsLayer', trips,
    get_path='waypoints.map(d => d.coordinates)',
    get_timestamps='waypoints.map(d => d.timestamp)',
    get_color=[253, 128, 93],
    current_time=500, trail_length=180,
)

pydeck can describe TripsLayer, but a standalone Python export does not create an animation loop; the current_time property must be updated by a frontend or widget.

Choose a basemap styleset-map-style

deck = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    map_style='light',
)

Style availability, remote tiles, and credentials depend on the selected map provider; the overlay can render even when the basemap fails.

Render layers without map tilesrender-without-basemap

deck = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    map_style=None,
)

This removes provider and token requirements but leaves only the deck.gl canvas, so add enough geographic context in your own layers.

Write an interactive HTML fileexport-html

deck.to_html(
    'map.html',
    open_browser=False,
    notebook_display=False,
)

Embedded data can make the HTML very large, and remote basemap styles or tiles still need network access unless you remove them.

Set camera bearing and pitchfit-camera-manually

view_state = pdk.ViewState(
    longitude=-73.98, latitude=40.75,
    zoom=10, pitch=45, bearing=-20,
)
deck = pdk.Deck(layers=[layer], initial_view_state=view_state)

ViewState is an initial camera, not automatic bounds fitting; calculate a suitable center and zoom when the data extent varies.

Alternatives

PackageRegistryPick it when
plotlyPyPIYou need a broader charting system with maps plus conventional statistical charts and static export options
foliumPyPIYou want Leaflet maps, markers, and plugins and do not need deck.gl's GPU layer model
ipyleafletPyPIYou need two-way Jupyter widget interaction around a Leaflet map