bindings/pydeck/examples/03 - Event handlers and data selection in pydeck.ipynb
Often it's easier to use a visual application to draw a shape than define a geometry in code. Here we'll explore how pydeck can be used to select data and pass that selected data back to the Jupyter kernel for use in Pandas.
Currently this notebook runs against live data, and there is a slight chance that the source data will be unavailable.
Here we'll use the live taxi location API provided by the government of Singapore.
import pydeck as pdk
DATA_URL = 'https://api.data.gov.sg/v1/transport/taxi-availability'
COLOR_RANGE = [
[255, 255, 178, 25],
[254, 217, 118, 85],
[254, 178, 76, 127],
[253, 141, 60, 170],
[240, 59, 32, 212],
[189, 0, 38, 255]
]
import pandas as pd
import requests
json = requests.get(DATA_URL).json()
df = pd.DataFrame(json["features"][0]["geometry"]["coordinates"])
df.columns = ['lng', 'lat']
viewport = pdk.data_utils.compute_view(df[['lng', 'lat']])
layer = pdk.Layer(
'ScreenGridLayer',
df,
get_position=['lng', 'lat'],
cell_size_pixels=20,
color_range=COLOR_RANGE,
pickable=True,
auto_highlight=True)
r = pdk.Deck(layers=[layer], initial_view_state=viewport)
r.show()
Click the above visualization and then execute the cell below to pass data from the application to Python.
r.selected_data
You can also create more complex applications by drawing from the many widgets available within the ipywidgets library. Currently, pydeck supports a number of event handlers which can be linked to ipywidgets or elsewhere.
Here, we'll use ipywidgets to tell us the number of taxis in the current viewport.
from ipywidgets import HTML
text = HTML(value='Points in viewport:')
layer = pdk.Layer('ScatterplotLayer', df, get_position=['lng', 'lat'], get_fill_color=[255, 0, 0], get_radius=100)
r = pdk.Deck(layer, initial_view_state=viewport)
def filter_by_bbox(row, west_lng, east_lng, north_lat, south_lat):
return west_lng < row['lng'] < east_lng and south_lat < row['lat'] < north_lat
def filter_by_viewport(widget_instance, payload):
try:
west_lng, north_lat = payload['data']['nw']
east_lng, south_lat = payload['data']['se']
filtered_df = df[df.apply(lambda row: filter_by_bbox(row, west_lng, east_lng, north_lat, south_lat), axis=1)]
text.value = 'Points in viewport: %s' % int(filtered_df.count()['lng'])
except Exception as e:
text.value = 'Error: %s' % e
r.deck_widget.on_view_state_change(filter_by_viewport)
display(text)
r.show()