In [1]:
import pydeck as pdk
import pandas as pd

Plotting lights at night

NASA has collected global light emission data for over 30 years. The data set is a deeply fascinating one and has been used for news stories on the Syrian Civil War [1], North Korea [2], and economic growth [3].

In this notebook, we'll use a deck.gl HeatmapLayer to visualize some of the changes at different points in time.

Getting the data

The data for Chengdu, China, is cleaned and available below. Please note this data is meant for demonstration only.

In [2]:
LIGHTS_URL = 'https://raw.githubusercontent.com/ajduberstein/lights_at_night/master/chengdu_lights_at_night.csv'
df = pd.read_csv(LIGHTS_URL)
df.head()
Out[2]:
year lng lat brightness
0 1993 104.575 31.808 4
1 1993 104.583 31.808 4
2 1993 104.592 31.808 4
3 1993 104.600 31.808 4
4 1993 104.675 31.808 4

Setting the colors

pydeck does need to know the color for this data in advance of plotting it

In [3]:
df['color'] = df['brightness'].apply(lambda val: [255, val * 4,  255, 255])
df.sample(10)
Out[3]:
year lng lat brightness color
241716 2011 104.058 30.425 15 [255, 60, 255, 255]
45769 1995 103.625 30.725 4 [255, 16, 255, 255]
182963 2007 104.808 31.575 5 [255, 20, 255, 255]
280621 2005 104.117 30.475 7 [255, 28, 255, 255]
255291 2011 104.300 29.692 5 [255, 20, 255, 255]
145105 2003 103.700 29.717 3 [255, 12, 255, 255]
124635 2003 104.350 31.008 8 [255, 32, 255, 255]
54183 1995 105.033 29.567 13 [255, 52, 255, 255]
50580 1995 105.008 30.258 4 [255, 16, 255, 255]
163200 2013 104.200 30.692 53 [255, 212, 255, 255]

Plotting and interacting

We can plot this data set of light brightness by year, configuring a slider to filter the data as below:

In [4]:
plottable = df[df['year'] == 1993].to_dict(orient='records')

view_state = pdk.ViewState(
    latitude=31.0,
    longitude=104.5,
    zoom=8)
scatterplot = pdk.Layer(
    'HeatmapLayer',
    data=plottable,
    get_position=['lng', 'lat'],
    get_weight='brightness',
    opacity=0.5,
    pickable=False,
    get_radius=800)
r = pdk.Deck(
    layers=[scatterplot],
    initial_view_state=view_state,
    views=[pdk.View(type='MapView', controller=None)])
r.show()
/Users/andrewduberstein/Desktop/deck.gl/bindings/pydeck/pydeck/bindings/warnings.py:5: UserWarning: A Mapbox API key is not set, which will lead to a blank base map. If this is intentional, set map_provider=None. Otherwise, pass a Mapbox API key and consider setting this API key as an environment variable. See https://pydeck.gl/installation.html#getting-a-mapbox-api-key
  warnings.warn(
/Users/andrewduberstein/Desktop/deck.gl/bindings/pydeck/pydeck/bindings/warnings.py:14: UserWarning: The frontend widget did not render. To enable the widget, see https://pydeck.gl/installation.html#enabling-pydeck-for-jupyter. Alternatively, use .to_html(), https://pydeck.gl/deck.html?highlight=to_html#pydeck.bindings.deck.Deck.to_html
  warnings.warn(
In [5]:
import ipywidgets as widgets
from IPython.display import display
slider = widgets.IntSlider(1992, min=1993, max=2013, step=2)
def on_change(v):
    results = df[df['year'] == slider.value].to_dict(orient='records')
    scatterplot.data = results
    r.update()
    
slider.observe(on_change, names='value')
display(slider)