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
275910 2005 103.967 30.683 45 [255, 180, 255, 255]
154988 2013 104.317 31.200 15 [255, 60, 255, 255]
229158 2011 104.383 31.017 14 [255, 56, 255, 255]
216939 2007 103.658 29.517 3 [255, 12, 255, 255]
111864 2001 102.783 29.783 5 [255, 20, 255, 255]
102856 2001 104.017 30.558 32 [255, 128, 255, 255]
256587 2011 103.800 29.617 16 [255, 64, 255, 255]
286139 2005 104.683 30.192 5 [255, 20, 255, 255]
188185 2007 103.942 31.175 3 [255, 12, 255, 255]
12831 1993 103.700 29.608 5 [255, 20, 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,
    max_zoom=8,
    min_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()
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)