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".

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, or POST it:

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:

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.

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

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.

What review adds

  • Anchored threads on a region or a spike — see commenting 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 →

Related