{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pydeck as pdk\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plotting lights at night\n",
    "\n",
    "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]](https://time.com/3741451/syria-lights-civil-war-satellite/), North Korea [[2]](https://www.cbsnews.com/pictures/north-korea-hermit-country-space-photos/4/), and economic growth [[3]](https://qz.com/959563/nasas-black-marble-map-shows-the-light-of-human-population-centers-at-night-throughout-2016/).\n",
    "\n",
    "In this notebook, we'll use a deck.gl [HeatmapLayer](https://deck.gl/#/documentation/deckgl-api-reference/layers/heatmap-layer) to visualize some of the changes at different points in time.\n",
    "\n",
    "## Getting the data\n",
    "\n",
    "The data for Chengdu, China, is cleaned and available below. Please note this data is meant for demonstration only."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "LIGHTS_URL = 'https://raw.githubusercontent.com/ajduberstein/lights_at_night/master/chengdu_lights_at_night.csv'\n",
    "df = pd.read_csv(LIGHTS_URL)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Setting the colors\n",
    "pydeck does need to know the color for this data in advance of plotting it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df['color'] = df['brightness'].apply(lambda val: [255, val * 4,  255, 255])\n",
    "df.sample(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting and interacting\n",
    "\n",
    "We can plot this data set of light brightness by year, configuring a slider to filter the data as below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plottable = df[df['year'] == 1993].to_dict(orient='records')\n",
    "\n",
    "view_state = pdk.ViewState(\n",
    "    latitude=31.0,\n",
    "    longitude=104.5,\n",
    "    zoom=8)\n",
    "scatterplot = pdk.Layer(\n",
    "    'HeatmapLayer',\n",
    "    data=plottable,\n",
    "    get_position=['lng', 'lat'],\n",
    "    get_weight='brightness',\n",
    "    opacity=0.5,\n",
    "    pickable=False,\n",
    "    get_radius=800)\n",
    "r = pdk.Deck(\n",
    "    layers=[scatterplot],\n",
    "    initial_view_state=view_state,\n",
    "    views=[pdk.View(type='MapView', controller=None)])\n",
    "r.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import ipywidgets as widgets\n",
    "from IPython.display import display\n",
    "slider = widgets.IntSlider(1992, min=1993, max=2013, step=2)\n",
    "def on_change(v):\n",
    "    results = df[df['year'] == slider.value].to_dict(orient='records')\n",
    "    scatterplot.data = results\n",
    "    r.update()\n",
    "    \n",
    "slider.observe(on_change, names='value')\n",
    "display(slider)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
