Back to Deck Gl

A brief intro to pydeck

bindings/pydeck/examples/01 - Introduction.ipynb

9.3.25.5 KB
Original Source

A brief intro to pydeck

The pydeck library is made for visualizing data points in 2D or 3D maps. Specifically, it handles

  • rendering large (>1M points) data sets, like LIDAR point clouds or GPS pings
  • large-scale updates to data points, like plotting points with motion
  • making beautiful maps

Under the hood, it's powered by the deck.gl JavaScript framework.

pydeck is strongest when used in tandem with Pandas but doesn't have to be.

Please note that these demo notebooks are best when executed cell-by-cell, so ideally clone this repo or run it from mybinder.org.

python
import pydeck as pdk
print("Welcome to pydeck version", pdk.__version__)

There are three steps for most pydeck visualizations

We'll walk through pydeck using a visualization of vehicle accident data in the United Kingdom.

1. Choose your data

Here, we'll use the history of accident data throughout the United Kingdom. This data set presents the location of every latitude and longitude of car accidents in the UK in 2014 (source).

python
import pandas as pd

UK_ACCIDENTS_DATA = 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv'

pd.read_csv(UK_ACCIDENTS_DATA).head()

2. Configure the visualization: Choose your layer(s), viewport, and widget(s)

pydeck's Layer object takes two positional and many keyword arguments:

  • First, a string specifying the layer type, with our example below using 'HexagonLayer'
  • Next, a data URL–below you'll see the UK_ACCIDENTS_DATA that we set above, but we could alternately pass a data frame or list of dictionaries
  • Finally, keywords representing that layer's attributes–in our example, this would include elevation_scale, elevation_range, extruded, coverage. pickable=True also allows us to add a tooltip that appears on hover.
python
layer = pdk.Layer(
    'HexagonLayer',
    UK_ACCIDENTS_DATA,
    get_position=['lng', 'lat'],
    elevation_scale=50,
    pickable=True,
    auto_highlight=True,
    elevation_range=[0, 3000],
    extruded=True,                 
    coverage=1)

There is of course an entire catalog of layers which you're welcome to check out within the deck.gl documentation.

Configure your viewport

We also have to specifiy a ViewState object.

The ViewState object specifies a camera angle relative to the map data. If you don't want to manually specify it, the function pydeck.data_utils.compute_view can take your data and automatically zoom to it.

pydeck also provides some controls, most of which should be familiar from map applications throughout the web. By default, you can hold out and drag to rotate the map.

Configure your UI widgets

You may also want to add Widget objects to offer controls and information around the pydeck visualization. Browse the catalog of widgets within the deck.gl documentation.

python
layer = pdk.Layer(
    'HexagonLayer',
    UK_ACCIDENTS_DATA,
    get_position=['lng', 'lat'],
    auto_highlight=True,
    elevation_scale=50,
    pickable=True,
    elevation_range=[0, 3000],
    extruded=True,                 
    coverage=1)

# Set the viewport location
view_state = pdk.ViewState(
    longitude=-1.415,
    latitude=52.2323,
    zoom=6,
    min_zoom=5,
    max_zoom=15,
    pitch=40.5,
    bearing=-27.36)

# Add a compass and zoom control
compass_widget = pdk.Widget('CompassWidget', placement='top-right')
zoom_widget = pdk.Widget('ZoomWidget', placement='top-right')

# Combined all of it and render a viewport
r = pdk.Deck(layers=[layer], initial_view_state=view_state, widgets=[compass_widget, zoom_widget])
r.show()
python
# Create a custom view with scroll zoom disabled
view = pdk.View(type='MapView', controller={'scrollZoom': False})

# Render with the custom view
r_no_scroll = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    views=[view],
    widgets=[compass_widget, zoom_widget]
)
r_no_scroll.show()

Controlling map interactions

By default, the map captures scroll wheel events for zooming. In a notebook environment, this can be annoying when you're trying to scroll the page. You can disable scroll zoom while keeping other interactions enabled by passing a controller configuration to the View:

python
view = pdk.View(type='MapView', controller={'scrollZoom': False})

This allows you to:

  • Still zoom with double-click
  • Still pan by dragging
  • Still rotate by holding Ctrl/Cmd and dragging
  • Scroll the notebook page without accidentally zooming the map

Render an update to the visualization

Execute the cell below and look at the map in the cell above–you'll notice a seamless rendered update on the map

python
layer.elevation_range = [0, 10000]

r.update()

Support updates over time

We can combine any Python function with our work here, of course. Execute the cell below to update our map above over time.

python
import time
r.show()
python
for i in range(0, 10000, 1000):
    layer.elevation_range = [0, i]
    r.update()
    time.sleep(0.1)

pydeck without Jupyter

If you prefer not to use Jupyter or you'd like to export your map to a separate file, you can also write out maps to HTML locally using the .to_html function.

python
r.to_html()