# Share a pydeck Map — Keep the Pan, Zoom and Tooltips

Canonical: https://commareports.com/share-pydeck-map
Published: 2026-09-08

> deck.to_html() writes a WebGL map that only opens locally. Publish it to Comma for a URL where the layers, camera and tooltips still work for everyone.

# Share a pydeck map

pydeck gives Python a real WebGL mapping stack: hexagon aggregation over
millions of points, arc layers, 3D extrusion, a camera you fly around. It is
the output that most obviously loses its meaning as a screenshot, because the
insight is usually "look at this when you rotate it".

```python
import pydeck as pdk

layer = pdk.Layer(
    "HexagonLayer", data=df,
    get_position=["lon", "lat"],
    radius=200, elevation_scale=4, extruded=True, pickable=True,
)
deck = pdk.Deck(
    layers=[layer],
    initial_view_state=pdk.ViewState(latitude=51.50, longitude=-0.12, zoom=11, pitch=45),
    tooltip={"text": "{elevationValue} rides"},
)
deck.to_html("map.html")
```

`to_html` gives you a file. Which then does the usual thing: too big to paste,
downloads instead of opening when attached, and unpreviewable in chat.

## Publish it

Drag `map.html` into [the app](https://commareports.com/), or POST it:

```bash
curl -fsS -X POST "https://commareports.com/api/v1/reports" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html map.html \
        --arg t "Ride density — London, Q3" '{title: $t, html: $html}')"
```

Report HTML renders with scripts enabled inside a sandboxed iframe
(`allow-scripts`, no `allow-same-origin`), and WebGL is available inside it. So
the reader gets the map: pan, zoom, pitch, the tooltip on hover, and the layer
controls if you added them.

If `to_html` emitted the data as a sibling file rather than inlining it, publish
the folder instead of the single file — the JSON uploads as an asset and its
relative reference is rewritten to the uploaded copy, which is the step a
`file://` origin cannot perform.

## Check the token before you publish

This is the pydeck-specific trap. If you use a Mapbox base map, `to_html`
embeds your access token in the page:

```python
pdk.Deck(..., map_provider="mapbox", api_keys={"mapbox": MAPBOX_KEY})
```

Publish that with public access and the token is public. Three ways out, in
order of preference:

1. **Use a carto base map** (`map_provider="carto"`), which needs no token.
2. **Restrict the token** by URL in the Mapbox dashboard.
3. **Keep the report private** — team, domain-gated or named reviewers. See the
   [sharing model](/docs/sharing).

The same applies to any base map provider with a key.

## Aggregate before you publish

A `ScatterplotLayer` over two million raw points produces an enormous HTML file
and a map that reads as a solid blob. `HexagonLayer` or `GridLayer` with
server-side aggregation produces a smaller file *and* a more readable map — the
constraint and the design advice point the same way here.

## Refreshing maps

```bash
python build_map.py     # regenerates map.html from the warehouse

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html map.html \
        --arg t "Ride density — week $(date +%V)" '{title: $t, html: $html}')"
```

One URL per map, a revision per refresh — see
[scheduled HTML reports](/features/routines/scheduled-html-reports).

## What review adds

- **Anchored threads** on a region or a spike — see
  [commenting on HTML](/comment-on-html).
- **Revisions**, so week-over-week change is visible.
- **Access per report** — location data is frequently personal data. Set this
  deliberately.

## Limits

- **Entry HTML: 5 MB.** Assets: 25 MB per file, 250 MB and 500 files total.
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision
history.

**[Publish a map →](https://commareports.com/)**

### Related

- [Share a Folium map](/share-folium-map) · [Share a D3 visualization](/share-d3-visualization)
- [Share a Plotly HTML file](/share-plotly-html) · [Share a Bokeh plot](/share-bokeh-plot)
- [Share a Jupyter notebook as HTML](/share-jupyter-notebook-html) · [Interactive HTML reports](/interactive-html-reports)
