Install

In [1]:
!pip3 install pydeck
Collecting pydeck
  Downloading https://files.pythonhosted.org/packages/c2/d6/f7b5ed0cde59833077a9c65ce2c08dca06557edd42eda70046441761a8ce/pydeck-0.1.dev5-py2.py3-none-any.whl (66kB)
     |████████████████████████████████| 71kB 233kB/s eta 0:00:01
Collecting jinja2>=2.10.1 (from pydeck)
  Downloading https://files.pythonhosted.org/packages/65/e0/eb35e762802015cab1ccee04e8a277b03f1d8e53da3ec3106882ec42558b/Jinja2-2.10.3-py2.py3-none-any.whl (125kB)
     |████████████████████████████████| 133kB 595kB/s eta 0:00:01
Requirement already satisfied: traitlets>=4.3.2 in /usr/local/lib/python3.7/site-packages (from pydeck) (4.3.2)
Requirement already satisfied: ipywidgets<8,>=7.0.0 in /usr/local/lib/python3.7/site-packages (from pydeck) (7.5.0)
Collecting ipykernel>=5.1.2; python_version >= "3.4" (from pydeck)
  Downloading https://files.pythonhosted.org/packages/e1/92/8fec943b5b81078399f969f00557804d884c96fcd0bc296e81a2ed4fd270/ipykernel-5.1.3-py3-none-any.whl (116kB)
     |████████████████████████████████| 122kB 112kB/s eta 0:00:01
Requirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python3.7/site-packages (from jinja2>=2.10.1->pydeck) (1.1.1)
Requirement already satisfied: decorator in /usr/local/lib/python3.7/site-packages (from traitlets>=4.3.2->pydeck) (4.4.0)
Requirement already satisfied: ipython-genutils in /usr/local/lib/python3.7/site-packages (from traitlets>=4.3.2->pydeck) (0.2.0)
Requirement already satisfied: six in /usr/local/lib/python3.7/site-packages (from traitlets>=4.3.2->pydeck) (1.12.0)
Requirement already satisfied: nbformat>=4.2.0 in /usr/local/lib/python3.7/site-packages (from ipywidgets<8,>=7.0.0->pydeck) (4.4.0)
Requirement already satisfied: ipython>=4.0.0; python_version >= "3.3" in /usr/local/lib/python3.7/site-packages (from ipywidgets<8,>=7.0.0->pydeck) (7.5.0)
Requirement already satisfied: widgetsnbextension~=3.5.0 in /usr/local/lib/python3.7/site-packages (from ipywidgets<8,>=7.0.0->pydeck) (3.5.0)
Requirement already satisfied: appnope; platform_system == "Darwin" in /usr/local/lib/python3.7/site-packages (from ipykernel>=5.1.2; python_version >= "3.4"->pydeck) (0.1.0)
Requirement already satisfied: jupyter-client in /usr/local/lib/python3.7/site-packages (from ipykernel>=5.1.2; python_version >= "3.4"->pydeck) (5.2.4)
Requirement already satisfied: tornado>=4.2 in /usr/local/lib/python3.7/site-packages (from ipykernel>=5.1.2; python_version >= "3.4"->pydeck) (6.0.2)
Requirement already satisfied: jupyter-core in /usr/local/lib/python3.7/site-packages (from nbformat>=4.2.0->ipywidgets<8,>=7.0.0->pydeck) (4.4.0)
Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in /usr/local/lib/python3.7/site-packages (from nbformat>=4.2.0->ipywidgets<8,>=7.0.0->pydeck) (3.0.1)
Requirement already satisfied: setuptools>=18.5 in /usr/local/lib/python3.7/site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (41.0.1)
Requirement already satisfied: pexpect; sys_platform != "win32" in /usr/local/lib/python3.7/site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (4.7.0)
Requirement already satisfied: jedi>=0.10 in /usr/local/lib/python3.7/site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (0.13.3)
Requirement already satisfied: pickleshare in /usr/local/lib/python3.7/site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (0.7.5)
Requirement already satisfied: prompt-toolkit<2.1.0,>=2.0.0 in /usr/local/lib/python3.7/site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (2.0.9)
Requirement already satisfied: backcall in /usr/local/lib/python3.7/site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (0.1.0)
Requirement already satisfied: pygments in /usr/local/lib/python3.7/site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (2.4.2)
Requirement already satisfied: notebook>=4.4.1 in /usr/local/lib/python3.7/site-packages (from widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (5.7.8)
Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/site-packages/python_dateutil-2.7.3-py3.7.egg (from jupyter-client->ipykernel>=5.1.2; python_version >= "3.4"->pydeck) (2.7.3)
Requirement already satisfied: pyzmq>=13 in /usr/local/lib/python3.7/site-packages (from jupyter-client->ipykernel>=5.1.2; python_version >= "3.4"->pydeck) (18.0.1)
Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets<8,>=7.0.0->pydeck) (19.1.0)
Requirement already satisfied: pyrsistent>=0.14.0 in /usr/local/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets<8,>=7.0.0->pydeck) (0.15.2)
Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.7/site-packages (from pexpect; sys_platform != "win32"->ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (0.6.0)
Requirement already satisfied: parso>=0.3.0 in /usr/local/lib/python3.7/site-packages (from jedi>=0.10->ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (0.4.0)
Requirement already satisfied: wcwidth in /usr/local/lib/python3.7/site-packages (from prompt-toolkit<2.1.0,>=2.0.0->ipython>=4.0.0; python_version >= "3.3"->ipywidgets<8,>=7.0.0->pydeck) (0.1.7)
Requirement already satisfied: Send2Trash in /usr/local/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (1.5.0)
Requirement already satisfied: prometheus-client in /usr/local/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (0.7.1)
Requirement already satisfied: nbconvert in /usr/local/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (5.5.0)
Requirement already satisfied: terminado>=0.8.1 in /usr/local/lib/python3.7/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (0.8.2)
Requirement already satisfied: bleach in /usr/local/lib/python3.7/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (3.1.0)
Requirement already satisfied: defusedxml in /usr/local/lib/python3.7/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (0.6.0)
Requirement already satisfied: testpath in /usr/local/lib/python3.7/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (0.4.2)
Requirement already satisfied: entrypoints>=0.2.2 in /usr/local/lib/python3.7/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (0.3)
Requirement already satisfied: pandocfilters>=1.4.1 in /usr/local/lib/python3.7/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (1.4.2)
Requirement already satisfied: mistune>=0.8.1 in /usr/local/lib/python3.7/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (0.8.4)
Requirement already satisfied: webencodings in /usr/local/lib/python3.7/site-packages (from bleach->nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.0.0->pydeck) (0.5.1)
ERROR: numpydoc 0.9.1 requires sphinx>=1.6.5, which is not installed.
ERROR: flask 1.1.0 has requirement Werkzeug>=0.15, but you'll have werkzeug 0.14.1 which is incompatible.
ERROR: dash 1.0.0 has requirement dash-core-components==1.0.0, but you'll have dash-core-components 0.14.0 which is incompatible.
ERROR: dash 1.0.0 has requirement dash-html-components==1.0.0, but you'll have dash-html-components 0.8.0 which is incompatible.
ERROR: dash 1.0.0 has requirement dash-renderer==1.0.0, but you'll have dash-renderer 0.11.1 which is incompatible.
ERROR: apache-airflow 1.10.3rc2 has requirement jinja2<=2.10.0,>=2.7.3, but you'll have jinja2 2.10.3 which is incompatible.
Installing collected packages: jinja2, ipykernel, pydeck
  Found existing installation: Jinja2 2.10
    Uninstalling Jinja2-2.10:
      Successfully uninstalled Jinja2-2.10
  Found existing installation: ipykernel 5.1.1
    Uninstalling ipykernel-5.1.1:
      Successfully uninstalled ipykernel-5.1.1
Successfully installed ipykernel-5.1.3 jinja2-2.10.3 pydeck-0.1.dev5
In [3]:
!jupyter nbextension install --sys-prefix --symlink --overwrite --py pydeck
!jupyter nbextension enable --sys-prefix --py pydeck
Installing /usr/local/lib/python3.7/site-packages/pydeck/nbextension/static -> pydeck
Symlinking: /usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/share/jupyter/nbextensions/pydeck -> /usr/local/lib/python3.7/site-packages/pydeck/nbextension/static
- Validating: OK

    To initialize this nbextension in the browser every time the notebook (or other app) loads:
    
          jupyter nbextension enable pydeck --py --sys-prefix
    
Enabling notebook extension pydeck/extensionRequires...
      - Validating: OK
In [1]:
# export MAPBOX_API_KEY="your key"

공식 홈페이지 예시

In [11]:
import pydeck

# 2014 locations of car accidents in the UK
UK_ACCIDENTS_DATA = ('https://raw.githubusercontent.com/uber-common/'
                     'deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv')

# Define a layer to display on a map
layer = pydeck.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 = pydeck.ViewState(
    longitude=-1.415,
    latitude=52.2323,
    zoom=6,
    min_zoom=5,
    max_zoom=15,
    pitch=40.5,
    bearing=-27.36)

# Render
r = pydeck.Deck(layers=[layer], initial_view_state=view_state)
# r.to_html('demo.html')
r.show()

Conway의 생명 게임

In [12]:
import random

def new_board(x, y, num_live_cells=2, num_dead_cells=3):
    """Initializes a board for Conway's Game of Life"""
    board = []
    for i in range(0, y):
        # Defaults to a 3:2 dead cell:live cell ratio
        board.append([random.choice([0] * num_dead_cells + [1] * num_live_cells) for _ in range(0, x)])
    return board

        
def get(board, x, y):
    """Return the value at location (x, y) on a board, wrapping around if out-of-bounds"""
    return board[y % len(board)][x % len(board[0])]


def assign(board, x, y, value):
    """Assigns a value at location (x, y) on a board, wrapping around if out-of-bounds"""
    board[y % len(board)][x % len(board[0])] = value


def count_neighbors(board, x, y):
    """Counts the number of living neighbors a cell at (x, y) on a board has"""
    return sum([
        get(board, x - 1, y),
        get(board, x + 1, y),
        get(board, x, y - 1),
        get(board, x, y + 1),
        get(board, x + 1, y + 1),
        get(board, x + 1, y - 1),
        get(board, x - 1, y + 1),
        get(board, x - 1, y - 1)])


def process_life(board):
    """Creates the next iteration from a passed state of Conway's Game of Life"""
    next_board = new_board(len(board[0]), len(board))
    for y in range(0, len(board)):
        for x in range(0, len(board[y])):
            num_neighbors = count_neighbors(board, x, y)
            is_alive = get(board, x, y) == 1
            if num_neighbors < 2 and is_alive:
                assign(next_board, x, y, 0)
            elif 2 <= num_neighbors <= 3 and is_alive:
                assign(next_board, x, y, 1)
            elif num_neighbors > 3 and is_alive:
                assign(next_board, x, y, 0)
            elif num_neighbors == 3 and not is_alive:
                assign(next_board, x, y, 1)
            else:
                assign(next_board, x, y, 0)
    return next_board
In [13]:
from IPython.display import clear_output
import time

def draw_board(board):
    res = ''
    for row in board:
        for col in row:
            if col == 1:
                res += '* '
            else:
                res += '  '
        res += '\n'
    return res

board = new_board(20, 20)

NUM_ITERATIONS = 100

for i in range(0, NUM_ITERATIONS):
    print('Iteration ' + str(i + 1))
    board = process_life(board)
    res = draw_board(board)
    print(res)
    time.sleep(0.1)
    clear_output(wait=True)
Iteration 100
                                        
                                        
                                        
                                        
      *                                 
      *                                 
      *                                 
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        

In [14]:
import numpy as np
import pandas as pd
import pydeck as deck

PINK = [155, 155, 255, 245]
PURPLE = [255, 155, 255, 245]

SCALING_FACTOR = 1000.0

def convert_board_to_df(board):
    """Makes the board matrix into a list for easier processing"""
    rows = []
    for x in range(0, len(board[0])):
        for y in range(0, len(board)):
            rows.append([[x / SCALING_FACTOR, y / SCALING_FACTOR], PURPLE if board[y][x] else PINK])
    return pd.DataFrame(rows, columns=['position', 'color'])

board = new_board(30, 30)
records = convert_board_to_df(board)
layer = deck.Layer(
    'PointCloudLayer',
    records,
    get_position='position',
    get_color='color',
    get_radius=40)
view_state = deck.ViewState(latitude=0.00, longitude=0.00, zoom=13, bearing=44, pitch=45)
r = deck.Deck(layers=[layer], initial_view_state=view_state, map_style='')
r.show()
In [17]:
NUM_ITERATIONS = 100
display(r.show())
for i in range(0, NUM_ITERATIONS):
    board = process_life(board)
    records = convert_board_to_df(board)
    layer.data = records
    r.update()
    time.sleep(0.1)
In [20]:
import pandas as pd

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

pd.read_csv(UK_ACCIDENTS_DATA).head()
Out[20]:
lng lat
0 -0.198465 51.505538
1 -0.178838 51.491836
2 -0.205590 51.514910
3 -0.208327 51.514952
4 -0.206022 51.496572
In [24]:
UK_ACCIDENTS_DATA
Out[24]:
'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv'
In [29]:
layer = pydeck.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 = pydeck.ViewState(
    longitude=-1.415,
    latitude=52.2323,
    zoom=6,
    min_zoom=5,
    max_zoom=15,
    pitch=40.5,
    bearing=-27.36)

# Combined all of it and render a viewport
r = pydeck.Deck(layers=[layer], initial_view_state=view_state)
r.show()
In [33]:
layer.elevation_range = [0, 10000]

r.update()
In [26]:
import pydeck as pdk
In [28]:
pdk.Deck?
In [34]:
import time
r.show()
In [35]:
for i in range(0, 10000, 1000):
    layer.elevation_range = [0, i]
    r.update()
    time.sleep(0.1)

Scatter Plots

In [36]:
import pandas as pd
from pydeck import (
    data_utils,
    Deck,
    Layer
)

# First, let's use Pandas to download our data
URL = 'https://raw.githubusercontent.com/ajduberstein/data_sets/master/beijing_subway_station.csv'
df = pd.read_csv(URL)
df.head()
Out[36]:
lat lng osm_id station_name chinese_name opening_date color line_name
0 39.940249 116.456359 1351272524 Agricultural Exhibition Center 农业展览馆 2008-07-19 [0, 146, 188, 255] Line 10
1 39.955570 116.388507 5057476994 Andelibeijie 安德里北街 2015-12-26 [0, 155, 119, 255] Line 8 (North section)
2 39.947729 116.402067 339088654 Andingmen 安定门 1984-09-20 [0, 75, 135, 255] Line 2
3 40.011026 116.263981 1362259113 Anheqiao North 安河桥北 2009-09-28 [0, 140, 149, 255] Line 4
4 39.967112 116.388398 5305505996 Anhuaqiao 安华桥 2012-12-30 [0, 155, 119, 255] Line 8 (North section)
In [37]:
from ast import literal_eval
# We have to re-code position to be one field in a list, so we'll do that here:
# The CSV encodes the [R, G, B, A] color values listed in it as a string
df['color'] = df.apply(lambda x: literal_eval(x['color']), axis=1)
In [38]:
df.head()
Out[38]:
lat lng osm_id station_name chinese_name opening_date color line_name
0 39.940249 116.456359 1351272524 Agricultural Exhibition Center 农业展览馆 2008-07-19 [0, 146, 188, 255] Line 10
1 39.955570 116.388507 5057476994 Andelibeijie 安德里北街 2015-12-26 [0, 155, 119, 255] Line 8 (North section)
2 39.947729 116.402067 339088654 Andingmen 安定门 1984-09-20 [0, 75, 135, 255] Line 2
3 40.011026 116.263981 1362259113 Anheqiao North 安河桥北 2009-09-28 [0, 140, 149, 255] Line 4
4 39.967112 116.388398 5305505996 Anhuaqiao 安华桥 2012-12-30 [0, 155, 119, 255] Line 8 (North section)
In [39]:
# Use pydeck's data_utils module to fit a viewport to the central 90% of the data
viewport = data_utils.compute_view(points=df[['lng', 'lat']], view_proportion=0.9)
auto_zoom_map = Deck(layers=None, initial_view_state=viewport)
auto_zoom_map.show()
In [40]:
from IPython.core.display import display
import ipywidgets

year = 2019

scatterplot = Layer(
    'ScatterplotLayer',
    df,
    id='scatterplot-layer',
    get_radius=500,
    get_fill_color='color',
    get_position='[lng, lat]')
r = Deck(layers=[scatterplot], initial_view_state=viewport)

# Create an HTML header to display the year
display_el = ipywidgets.HTML('<h1>{}</h1>'.format(year))
display(display_el)
# Show the current visualization
r.show()
In [41]:
import time
for y in range(1971, 2020):
    scatterplot.data = df[df['opening_date'] <= str(y)]
    year = y
    # Reset the header to display the year
    display_el.value = '<h1>{}</h1>'.format(year)
    r.update()
    time.sleep(0.2)

Using pydeck to manipulate data

In [42]:
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]
]
In [43]:
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,
    cell_size_pixels=20,
    color_range=COLOR_RANGE,
    get_position='[lng, lat]',
    pickable=True,
    auto_highlight=True)
r = pdk.Deck(layers=[layer], initial_view_state=viewport)
In [44]:
r.show()
In [46]:
pd.DataFrame([r.deck_widget.selected_data])
Out[46]:
cellCount cellWeight maxCellWieght totalCount
0 59 59 232 2595

Plotting massive data sets.ipynb

In [47]:
import pandas as pd
all_lidar = pd.concat([
    pd.read_csv('https://raw.githubusercontent.com/ajduberstein/kitti_subset/master/kitti_1.csv'),
    pd.read_csv('https://raw.githubusercontent.com/ajduberstein/kitti_subset/master/kitti_2.csv'),
    pd.read_csv('https://raw.githubusercontent.com/ajduberstein/kitti_subset/master/kitti_3.csv'),
    pd.read_csv('https://raw.githubusercontent.com/ajduberstein/kitti_subset/master/kitti_4.csv'),
])

# Filter to one frame of data
lidar = all_lidar[all_lidar['source'] == 136]
lidar.loc[: , ['x', 'y']] = lidar[['x', 'y']] / 10000
/usr/local/lib/python3.7/site-packages/pandas/core/indexing.py:543: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self.obj[item] = s
In [48]:
import pydeck as pdk


point_cloud = pdk.Layer(
    'PointCloudLayer',
    lidar[['x', 'y', 'z']],
    get_position='[x, y, z * 10]',
    get_normal=[0, 0, 1],
    get_color=[255, 0, 100, 200],
    pickable=True,  
    auto_highlight=True,
    point_size=1)


view_state = pdk.data_utils.compute_view(lidar[['x', 'y']], 0.9)
view_state.max_pitch = 360
view_state.pitch = 80
view_state.bearing = 120

r = pdk.Deck(
    point_cloud,
    initial_view_state=view_state,
    map_style='')
r.show()
In [49]:
import time
from collections import deque

# Choose a handful of frames to loop through
frame_buffer = deque([42, 56, 81, 95])
print('Press the stop icon to exit')
while True:
    current_frame = frame_buffer[0]
    lidar = all_lidar[all_lidar['source'] == current_frame]
    r.layers[0].get_position = '[x / 10000, y / 10000, z * 10]'
    r.layers[0].data = lidar.to_dict(orient='records')
    frame_buffer.rotate()
    r.update()
    time.sleep(0.5)
Press the stop icon to exit
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-49-03782f910cca> in <module>
     12     frame_buffer.rotate()
     13     r.update()
---> 14     time.sleep(0.5)

KeyboardInterrupt: 

Interacting with other Jupyter widgets.ipynb

In [50]:
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[50]:
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
In [ ]:
df['color'] = df['brightness'].apply(lambda val: [255, val * 4,  255, 255])
df.sample(10)
In [71]:
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 [72]:
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)
In [ ]:
tooltip = {
   "html": "<b>Elevation Value:</b> {elevationValue}",
   "style": {
        "backgroundColor": "steelblue",
        "color": "white"
   }
}

Tooltip

In [55]:
import pydeck as pdk

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)

# Combined all of it and render a viewport
r = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    tooltip={
        'html': '<b>Elevation Value:</b> {elevationValue}',
        'style': {
            'color': 'white'
        }
    }
)
r.show()
  • 그냥 텍스트로 하기
In [54]:
import pydeck as pdk

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)

# Combined all of it and render a viewport
r = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    tooltip = {
    "text": "Elevation: {elevationValue}"
    }
)
r.show()
  • Tooltip을 그냥 True값만 주기
In [56]:
import pydeck as pdk

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)

# Combined all of it and render a viewport
r = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    tooltip=True
)
r.show()
In [57]:
UK_ACCIDENTS_DATA = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv'

uk_data = pd.read_csv(UK_ACCIDENTS_DATA)
In [58]:
uk_data.head()
Out[58]:
lng lat
0 -0.198465 51.505538
1 -0.178838 51.491836
2 -0.205590 51.514910
3 -0.208327 51.514952
4 -0.206022 51.496572

미국 택시 데이터 시각화

In [87]:
query = """
SELECT 
    *
FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015` 
WHERE EXTRACT(MONTH from pickup_datetime) = 1
LIMIT 100000
"""
In [63]:
%%time
taxi_df = pd.read_gbq(query=query, dialect='standard', project_id='geultto')
CPU times: user 8.49 s, sys: 536 ms, total: 9.03 s
Wall time: 1min

GridLayer

  • 10만개 데이터
In [91]:
arc_layer = pdk.Layer(
    'GridLayer',
    taxi_df,
    get_position='[pickup_longitude, pickup_latitude]',
    pickable=True, 
    auto_highlight=True,
    tooltip=True
)

nyc_center = [-73.9808, 40.7648] 
view_state = pdk.ViewState(longitude=nyc_center[0], latitude=nyc_center[1], zoom=9)

r = pdk.Deck(layers=[arc_layer], initial_view_state=view_state)
r.show()

Arc Layer

In [106]:
zip_code_query = """
WITH base_data AS 
(
  SELECT 
    nyc_taxi.*, 
    pickup.zip_code as pickup_zip_code,
    pickup.internal_point_lat as pickup_zip_code_lat,
    pickup.internal_point_lon as pickup_zip_code_lon,
    dropoff.zip_code as dropoff_zip_code,
    dropoff.internal_point_lat as dropoff_zip_code_lat,
    dropoff.internal_point_lon as dropoff_zip_code_lon
  FROM (
    SELECT *
    FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015`
    WHERE 
        EXTRACT(MONTH from pickup_datetime) = 1
        and pickup_latitude <= 90 and pickup_latitude >= -90
        and dropoff_latitude <= 90 and dropoff_latitude >= -90
    ) AS nyc_taxi
  JOIN (
    SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon 
    FROM `bigquery-public-data.geo_us_boundaries.zip_codes`
    WHERE state_code='NY'
    ) AS pickup 
  ON ST_CONTAINS(pickup.zip_code_geom, st_geogpoint(pickup_longitude, pickup_latitude))
  JOIN (
    SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon 
    FROM `bigquery-public-data.geo_us_boundaries.zip_codes`
    WHERE state_code='NY' 
    ) AS dropoff
  ON ST_CONTAINS(dropoff.zip_code_geom, st_geogpoint(dropoff_longitude, dropoff_latitude))
  
)

SELECT 
  *
FROM base_data 
limit 10000
"""
In [107]:
%%time
taxi_df_by_zipcode = pd.read_gbq(query=zip_code_query, dialect='standard', project_id='geultto')
CPU times: user 1.15 s, sys: 56 ms, total: 1.2 s
Wall time: 42.3 s
In [108]:
taxi_df_by_zipcode.head(3)
Out[108]:
vendor_id pickup_datetime dropoff_datetime passenger_count trip_distance pickup_longitude pickup_latitude rate_code store_and_fwd_flag dropoff_longitude ... tip_amount tolls_amount imp_surcharge total_amount pickup_zip_code pickup_zip_code_lat pickup_zip_code_lon dropoff_zip_code dropoff_zip_code_lat dropoff_zip_code_lon
0 1 2015-01-08 23:10:48 2015-01-08 23:24:56 1 6.00 -73.964203 40.807423 None N -73.915398 ... 0.0 2.44 0.3 22.74 10027 40.811408 -73.953060 10463 40.880678 -73.906540
1 2 2015-01-10 23:41:12 2015-01-11 00:04:56 1 9.12 -73.950119 40.771908 None N -73.845802 ... 5.7 0.00 0.3 35.00 10075 40.773363 -73.956222 10461 40.847394 -73.840583
2 2 2015-01-01 01:19:22 2015-01-01 01:33:47 3 2.30 -73.936562 40.802635 None N -73.907959 ... 0.0 0.00 0.3 13.30 10035 40.795458 -73.929570 10455 40.814713 -73.908590

3 rows × 25 columns

In [114]:
arc_layer = pdk.Layer(
    'ArcLayer',
    taxi_df_by_zipcode,
    get_source_position='[pickup_zip_code_lon, pickup_zip_code_lat]',
    get_target_position='[dropoff_zip_code_lon, dropoff_zip_code_lat]',
    get_source_color='[255, 255, 120]', 
    get_target_color='[255, 0, 0]',
    get_widht='elevationValue',
    pickable=True, 
    auto_highlight=True,
)

nyc_center = [-73.9808, 40.7648] 
view_state = pdk.ViewState(longitude=nyc_center[0], latitude=nyc_center[1], zoom=9)

r = pdk.Deck(layers=[arc_layer], initial_view_state=view_state)
r.show()

Aggregate

In [160]:
agg_query = """
WITH base_data AS 
(
  SELECT 
    nyc_taxi.*, 
    pickup.zip_code as pickup_zip_code,
    pickup.internal_point_lat as pickup_zip_code_lat,
    pickup.internal_point_lon as pickup_zip_code_lon,
    dropoff.zip_code as dropoff_zip_code,
    dropoff.internal_point_lat as dropoff_zip_code_lat,
    dropoff.internal_point_lon as dropoff_zip_code_lon
  FROM (
    SELECT *
    FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015`
    WHERE 
        EXTRACT(MONTH from pickup_datetime) = 1
        and pickup_latitude <= 90 and pickup_latitude >= -90
        and dropoff_latitude <= 90 and dropoff_latitude >= -90
    ) AS nyc_taxi
  JOIN (
    SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon 
    FROM `bigquery-public-data.geo_us_boundaries.zip_codes`
    WHERE state_code='NY'
    ) AS pickup 
  ON ST_CONTAINS(pickup.zip_code_geom, st_geogpoint(pickup_longitude, pickup_latitude))
  JOIN (
    SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon 
    FROM `bigquery-public-data.geo_us_boundaries.zip_codes`
    WHERE state_code='NY' 
    ) AS dropoff
  ON ST_CONTAINS(dropoff.zip_code_geom, st_geogpoint(dropoff_longitude, dropoff_latitude))
  
)

SELECT 
  pickup_zip_code,
  pickup_zip_code_lat,
  pickup_zip_code_lon,
  dropoff_zip_code,
  dropoff_zip_code_lat,
  dropoff_zip_code_lon,
  COUNT(*) AS cnt
FROM base_data 
GROUP BY 1,2,3,4,5,6
limit 10000
"""
In [161]:
%%time
agg_df = pd.read_gbq(query=agg_query, dialect='standard', project_id='geultto')
CPU times: user 366 ms, sys: 63.2 ms, total: 429 ms
Wall time: 33.7 s
In [162]:
agg_df.head()
Out[162]:
pickup_zip_code pickup_zip_code_lat pickup_zip_code_lon dropoff_zip_code dropoff_zip_code_lat dropoff_zip_code_lon cnt
0 11358 40.760473 -73.796373 11358 40.760473 -73.796373 35
1 10039 40.830869 -73.936216 10456 40.829886 -73.908121 20
2 11420 40.673563 -73.817829 11201 40.693700 -73.989859 2
3 11416 40.684625 -73.849582 11419 40.688638 -73.822942 5
4 11230 40.622164 -73.965110 11218 40.643477 -73.976042 66
In [164]:
agg_df = agg_df.sort_values('cnt', ascending=False)
In [165]:
agg_df = agg_df[:100]
In [226]:
arc_layer = pdk.Layer(
    'ArcLayer',
    agg_df,
    get_source_position='[pickup_zip_code_lon, pickup_zip_code_lat]',
    get_target_position='[dropoff_zip_code_lon, dropoff_zip_code_lat]',
    get_source_color='[255, 255, 120]', 
    get_target_color='[255, 0, 0]',
    width_units='meters',
    get_width="1+10*cnt/500",
    pickable=True, 
    auto_highlight=True,
)

nyc_center = [-73.9808, 40.7648] 
view_state = pdk.ViewState(longitude=nyc_center[0], latitude=nyc_center[1], zoom=9)

r = pdk.Deck(layers=[arc_layer], initial_view_state=view_state,
             tooltip={
                 'html': '<b>count:</b> {cnt}',
                 'style': {
                     'color': 'white'
                 }
             }
            )
r.show()

요일별 위젯

In [230]:
agg_query2 = """
WITH base_data AS 
(
  SELECT 
    nyc_taxi.*, 
    pickup.zip_code as pickup_zip_code,
    pickup.internal_point_lat as pickup_zip_code_lat,
    pickup.internal_point_lon as pickup_zip_code_lon,
    dropoff.zip_code as dropoff_zip_code,
    dropoff.internal_point_lat as dropoff_zip_code_lat,
    dropoff.internal_point_lon as dropoff_zip_code_lon
  FROM (
    SELECT *
    FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015`
    WHERE 
        EXTRACT(MONTH from pickup_datetime) = 1
        and pickup_latitude <= 90 and pickup_latitude >= -90
        and dropoff_latitude <= 90 and dropoff_latitude >= -90
    LIMIT 100000
    ) AS nyc_taxi
  JOIN (
    SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon 
    FROM `bigquery-public-data.geo_us_boundaries.zip_codes`
    WHERE state_code='NY'
    ) AS pickup 
  ON ST_CONTAINS(pickup.zip_code_geom, st_geogpoint(pickup_longitude, pickup_latitude))
  JOIN (
    SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon 
    FROM `bigquery-public-data.geo_us_boundaries.zip_codes`
    WHERE state_code='NY' 
    ) AS dropoff
  ON ST_CONTAINS(dropoff.zip_code_geom, st_geogpoint(dropoff_longitude, dropoff_latitude))
  
)

SELECT 
  CAST(format_datetime('%u', pickup_datetime) AS INT64) -1 AS weekday,
  pickup_zip_code,
  pickup_zip_code_lat,
  pickup_zip_code_lon,
  dropoff_zip_code,
  dropoff_zip_code_lat,
  dropoff_zip_code_lon,
  COUNT(*) AS cnt
FROM base_data 
GROUP BY 1,2,3,4,5,6,7
"""
In [242]:
%%time
agg_df2 = pd.read_gbq(query=agg_query2, dialect='standard', project_id='geultto')
CPU times: user 586 ms, sys: 250 ms, total: 836 ms
Wall time: 5.95 s
In [243]:
agg_df2.head()
Out[243]:
weekday pickup_zip_code pickup_zip_code_lat pickup_zip_code_lon dropoff_zip_code dropoff_zip_code_lat dropoff_zip_code_lon cnt
0 6 10103 40.760780 -73.977670 10022 40.758630 -73.967949 3
1 4 10110 40.754499 -73.982256 10020 40.758236 -73.978833 1
2 3 11221 40.691340 -73.927879 11221 40.691340 -73.927879 2
3 3 11206 40.701954 -73.942358 11221 40.691340 -73.927879 3
4 6 10110 40.754499 -73.982256 10017 40.752359 -73.972489 1
In [244]:
default_data = agg_df2[agg_df2['weekday'] == 0].to_dict(orient='records')
In [250]:
arc_layer = pdk.Layer(
    'ArcLayer',
    default_data,
    get_source_position='[pickup_zip_code_lon, pickup_zip_code_lat]',
    get_target_position='[dropoff_zip_code_lon, dropoff_zip_code_lat]',
    get_source_color='[255, 255, 120]', 
    get_target_color='[255, 0, 0]',
    width_units='meters',
    get_width="1+10*cnt/500",
    pickable=True, 
    auto_highlight=True,
)

nyc_center = [-73.9808, 40.7648] 
view_state = pdk.ViewState(longitude=nyc_center[0], latitude=nyc_center[1], zoom=9)

r = pdk.Deck(layers=[arc_layer], initial_view_state=view_state,
             tooltip={
                 'html': '<b>count:</b> {cnt}',
                 'style': {
                     'color': 'white'
                 }
             }
            )
r.show()
In [246]:
# Widget 슬라이더 생성
import ipywidgets as widgets
from IPython.display import display
slider = widgets.IntSlider(0, min=0, max=6, step=1)

# Widget에서 사용할 함수 정의 
def on_change(v):
    results = agg_df2[agg_df2['weekday'] == slider.value].to_dict(orient='records')
    arc_layer.data = results
    r.update()

# Deck과 슬라이더 연결
slider.observe(on_change, names='value')
display(slider)
In [ ]: