{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Install" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting pydeck\n", "\u001b[?25l Downloading https://files.pythonhosted.org/packages/c2/d6/f7b5ed0cde59833077a9c65ce2c08dca06557edd42eda70046441761a8ce/pydeck-0.1.dev5-py2.py3-none-any.whl (66kB)\n", "\u001b[K |████████████████████████████████| 71kB 233kB/s eta 0:00:01\n", "\u001b[?25hCollecting jinja2>=2.10.1 (from pydeck)\n", "\u001b[?25l Downloading https://files.pythonhosted.org/packages/65/e0/eb35e762802015cab1ccee04e8a277b03f1d8e53da3ec3106882ec42558b/Jinja2-2.10.3-py2.py3-none-any.whl (125kB)\n", "\u001b[K |████████████████████████████████| 133kB 595kB/s eta 0:00:01\n", "\u001b[?25hRequirement already satisfied: traitlets>=4.3.2 in /usr/local/lib/python3.7/site-packages (from pydeck) (4.3.2)\n", "Requirement already satisfied: ipywidgets<8,>=7.0.0 in /usr/local/lib/python3.7/site-packages (from pydeck) (7.5.0)\n", "Collecting ipykernel>=5.1.2; python_version >= \"3.4\" (from pydeck)\n", "\u001b[?25l Downloading https://files.pythonhosted.org/packages/e1/92/8fec943b5b81078399f969f00557804d884c96fcd0bc296e81a2ed4fd270/ipykernel-5.1.3-py3-none-any.whl (116kB)\n", "\u001b[K |████████████████████████████████| 122kB 112kB/s eta 0:00:01\n", "\u001b[?25hRequirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python3.7/site-packages (from jinja2>=2.10.1->pydeck) (1.1.1)\n", "Requirement already satisfied: decorator in /usr/local/lib/python3.7/site-packages (from traitlets>=4.3.2->pydeck) (4.4.0)\n", "Requirement already satisfied: ipython-genutils in /usr/local/lib/python3.7/site-packages (from traitlets>=4.3.2->pydeck) (0.2.0)\n", "Requirement already satisfied: six in /usr/local/lib/python3.7/site-packages (from traitlets>=4.3.2->pydeck) (1.12.0)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "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)\n", "\u001b[31mERROR: numpydoc 0.9.1 requires sphinx>=1.6.5, which is not installed.\u001b[0m\n", "\u001b[31mERROR: flask 1.1.0 has requirement Werkzeug>=0.15, but you'll have werkzeug 0.14.1 which is incompatible.\u001b[0m\n", "\u001b[31mERROR: 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.\u001b[0m\n", "\u001b[31mERROR: 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.\u001b[0m\n", "\u001b[31mERROR: dash 1.0.0 has requirement dash-renderer==1.0.0, but you'll have dash-renderer 0.11.1 which is incompatible.\u001b[0m\n", "\u001b[31mERROR: 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.\u001b[0m\n", "Installing collected packages: jinja2, ipykernel, pydeck\n", " Found existing installation: Jinja2 2.10\n", " Uninstalling Jinja2-2.10:\n", " Successfully uninstalled Jinja2-2.10\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " Found existing installation: ipykernel 5.1.1\n", " Uninstalling ipykernel-5.1.1:\n", " Successfully uninstalled ipykernel-5.1.1\n", "Successfully installed ipykernel-5.1.3 jinja2-2.10.3 pydeck-0.1.dev5\n" ] } ], "source": [ "!pip3 install pydeck" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Installing /usr/local/lib/python3.7/site-packages/pydeck/nbextension/static -> pydeck\n", "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\n", "- Validating: \u001b[32mOK\u001b[0m\n", "\n", " To initialize this nbextension in the browser every time the notebook (or other app) loads:\n", " \n", " jupyter nbextension enable pydeck --py --sys-prefix\n", " \n", "Enabling notebook extension pydeck/extensionRequires...\n", " - Validating: \u001b[32mOK\u001b[0m\n" ] } ], "source": [ "!jupyter nbextension install --sys-prefix --symlink --overwrite --py pydeck\n", "!jupyter nbextension enable --sys-prefix --py pydeck" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# export MAPBOX_API_KEY=\"your key\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 공식 홈페이지 예시" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c870e0e52df24ecbb91f114dfb1ae8b3", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": -27.36, \"latitude\": 52.2323, \"longitude\": -1.415, \"m…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pydeck\n", "\n", "# 2014 locations of car accidents in the UK\n", "UK_ACCIDENTS_DATA = ('https://raw.githubusercontent.com/uber-common/'\n", " 'deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv')\n", "\n", "# Define a layer to display on a map\n", "layer = pydeck.Layer(\n", " 'HexagonLayer',\n", " UK_ACCIDENTS_DATA,\n", " get_position='[lng, lat]',\n", " auto_highlight=True,\n", " elevation_scale=50,\n", " pickable=True,\n", " elevation_range=[0, 3000],\n", " extruded=True, \n", " coverage=1)\n", "\n", "# Set the viewport location\n", "view_state = pydeck.ViewState(\n", " longitude=-1.415,\n", " latitude=52.2323,\n", " zoom=6,\n", " min_zoom=5,\n", " max_zoom=15,\n", " pitch=40.5,\n", " bearing=-27.36)\n", "\n", "# Render\n", "r = pydeck.Deck(layers=[layer], initial_view_state=view_state)\n", "# r.to_html('demo.html')\n", "r.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Conway의 생명 게임\n", "- [Example](https://github.com/uber/deck.gl/blob/master/bindings/python/pydeck/examples/06%20-%20Conway's%20Game%20of%20Life.ipynb)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "import random\n", "\n", "def new_board(x, y, num_live_cells=2, num_dead_cells=3):\n", " \"\"\"Initializes a board for Conway's Game of Life\"\"\"\n", " board = []\n", " for i in range(0, y):\n", " # Defaults to a 3:2 dead cell:live cell ratio\n", " board.append([random.choice([0] * num_dead_cells + [1] * num_live_cells) for _ in range(0, x)])\n", " return board\n", "\n", " \n", "def get(board, x, y):\n", " \"\"\"Return the value at location (x, y) on a board, wrapping around if out-of-bounds\"\"\"\n", " return board[y % len(board)][x % len(board[0])]\n", "\n", "\n", "def assign(board, x, y, value):\n", " \"\"\"Assigns a value at location (x, y) on a board, wrapping around if out-of-bounds\"\"\"\n", " board[y % len(board)][x % len(board[0])] = value\n", "\n", "\n", "def count_neighbors(board, x, y):\n", " \"\"\"Counts the number of living neighbors a cell at (x, y) on a board has\"\"\"\n", " return sum([\n", " get(board, x - 1, y),\n", " get(board, x + 1, y),\n", " get(board, x, y - 1),\n", " get(board, x, y + 1),\n", " get(board, x + 1, y + 1),\n", " get(board, x + 1, y - 1),\n", " get(board, x - 1, y + 1),\n", " get(board, x - 1, y - 1)])\n", "\n", "\n", "def process_life(board):\n", " \"\"\"Creates the next iteration from a passed state of Conway's Game of Life\"\"\"\n", " next_board = new_board(len(board[0]), len(board))\n", " for y in range(0, len(board)):\n", " for x in range(0, len(board[y])):\n", " num_neighbors = count_neighbors(board, x, y)\n", " is_alive = get(board, x, y) == 1\n", " if num_neighbors < 2 and is_alive:\n", " assign(next_board, x, y, 0)\n", " elif 2 <= num_neighbors <= 3 and is_alive:\n", " assign(next_board, x, y, 1)\n", " elif num_neighbors > 3 and is_alive:\n", " assign(next_board, x, y, 0)\n", " elif num_neighbors == 3 and not is_alive:\n", " assign(next_board, x, y, 1)\n", " else:\n", " assign(next_board, x, y, 0)\n", " return next_board\n", "\n" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Iteration 100\n", " \n", " \n", " \n", " \n", " * \n", " * \n", " * \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ] } ], "source": [ "from IPython.display import clear_output\n", "import time\n", "\n", "def draw_board(board):\n", " res = ''\n", " for row in board:\n", " for col in row:\n", " if col == 1:\n", " res += '* '\n", " else:\n", " res += ' '\n", " res += '\\n'\n", " return res\n", "\n", "board = new_board(20, 20)\n", "\n", "NUM_ITERATIONS = 100\n", "\n", "for i in range(0, NUM_ITERATIONS):\n", " print('Iteration ' + str(i + 1))\n", " board = process_life(board)\n", " res = draw_board(board)\n", " print(res)\n", " time.sleep(0.1)\n", " clear_output(wait=True)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "5ee1b3f477324368854d37828a0ec822", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 44, \"latitude\": 0.0, \"longitude\": 0.0, \"maxZoom\": 20…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import pandas as pd\n", "import pydeck as deck\n", "\n", "PINK = [155, 155, 255, 245]\n", "PURPLE = [255, 155, 255, 245]\n", "\n", "SCALING_FACTOR = 1000.0\n", "\n", "def convert_board_to_df(board):\n", " \"\"\"Makes the board matrix into a list for easier processing\"\"\"\n", " rows = []\n", " for x in range(0, len(board[0])):\n", " for y in range(0, len(board)):\n", " rows.append([[x / SCALING_FACTOR, y / SCALING_FACTOR], PURPLE if board[y][x] else PINK])\n", " return pd.DataFrame(rows, columns=['position', 'color'])\n", "\n", "board = new_board(30, 30)\n", "records = convert_board_to_df(board)\n", "layer = deck.Layer(\n", " 'PointCloudLayer',\n", " records,\n", " get_position='position',\n", " get_color='color',\n", " get_radius=40)\n", "view_state = deck.ViewState(latitude=0.00, longitude=0.00, zoom=13, bearing=44, pitch=45)\n", "r = deck.Deck(layers=[layer], initial_view_state=view_state, map_style='')\n", "r.show()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "5ee1b3f477324368854d37828a0ec822", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 44, \"latitude\": 0.0, \"longitude\": 0.0, \"maxZoom\": 20…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "NUM_ITERATIONS = 100\n", "display(r.show())\n", "for i in range(0, NUM_ITERATIONS):\n", " board = process_life(board)\n", " records = convert_board_to_df(board)\n", " layer.data = records\n", " r.update()\n", " time.sleep(0.1)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
lnglat
0-0.19846551.505538
1-0.17883851.491836
2-0.20559051.514910
3-0.20832751.514952
4-0.20602251.496572
\n", "
" ], "text/plain": [ " lng lat\n", "0 -0.198465 51.505538\n", "1 -0.178838 51.491836\n", "2 -0.205590 51.514910\n", "3 -0.208327 51.514952\n", "4 -0.206022 51.496572" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "\n", "UK_ACCIDENTS_DATA = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv'\n", "\n", "pd.read_csv(UK_ACCIDENTS_DATA).head()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv'" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "UK_ACCIDENTS_DATA" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "cec9dfb752d74fa7b7df1f34321e1960", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": -27.36, \"latitude\": 52.2323, \"longitude\": -1.415, \"m…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "layer = pydeck.Layer(\n", " 'HexagonLayer',\n", " UK_ACCIDENTS_DATA,\n", " get_position='[lng,lat]',\n", " auto_highlight=True,\n", " elevation_scale=50,\n", " pickable=True,\n", " elevation_range=[0, 3000],\n", " extruded=True, \n", " coverage=1)\n", "\n", "# Set the viewport location\n", "view_state = pydeck.ViewState(\n", " longitude=-1.415,\n", " latitude=52.2323,\n", " zoom=6,\n", " min_zoom=5,\n", " max_zoom=15,\n", " pitch=40.5,\n", " bearing=-27.36)\n", "\n", "# Combined all of it and render a viewport\n", "r = pydeck.Deck(layers=[layer], initial_view_state=view_state)\n", "r.show()" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "layer.elevation_range = [0, 10000]\n", "\n", "r.update()" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "import pydeck as pdk" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "pdk.Deck?" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "cec9dfb752d74fa7b7df1f34321e1960", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": -27.36, \"latitude\": 52.2323, \"longitude\": -1.415, \"m…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import time\n", "r.show()" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "for i in range(0, 10000, 1000):\n", " layer.elevation_range = [0, i]\n", " r.update()\n", " time.sleep(0.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Scatter Plots" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
latlngosm_idstation_namechinese_nameopening_datecolorline_name
039.940249116.4563591351272524Agricultural Exhibition Center农业展览馆2008-07-19[0, 146, 188, 255]Line 10
139.955570116.3885075057476994Andelibeijie安德里北街2015-12-26[0, 155, 119, 255]Line 8 (North section)
239.947729116.402067339088654Andingmen安定门1984-09-20[0, 75, 135, 255]Line 2
340.011026116.2639811362259113Anheqiao North安河桥北2009-09-28[0, 140, 149, 255]Line 4
439.967112116.3883985305505996Anhuaqiao安华桥2012-12-30[0, 155, 119, 255]Line 8 (North section)
\n", "
" ], "text/plain": [ " lat lng osm_id station_name \\\n", "0 39.940249 116.456359 1351272524 Agricultural Exhibition Center \n", "1 39.955570 116.388507 5057476994 Andelibeijie \n", "2 39.947729 116.402067 339088654 Andingmen \n", "3 40.011026 116.263981 1362259113 Anheqiao North \n", "4 39.967112 116.388398 5305505996 Anhuaqiao \n", "\n", " chinese_name opening_date color line_name \n", "0 农业展览馆 2008-07-19 [0, 146, 188, 255] Line 10 \n", "1 安德里北街 2015-12-26 [0, 155, 119, 255] Line 8 (North section) \n", "2 安定门 1984-09-20 [0, 75, 135, 255] Line 2 \n", "3 安河桥北 2009-09-28 [0, 140, 149, 255] Line 4 \n", "4 安华桥 2012-12-30 [0, 155, 119, 255] Line 8 (North section) " ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "from pydeck import (\n", " data_utils,\n", " Deck,\n", " Layer\n", ")\n", "\n", "# First, let's use Pandas to download our data\n", "URL = 'https://raw.githubusercontent.com/ajduberstein/data_sets/master/beijing_subway_station.csv'\n", "df = pd.read_csv(URL)\n", "df.head()" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "from ast import literal_eval\n", "# We have to re-code position to be one field in a list, so we'll do that here:\n", "# The CSV encodes the [R, G, B, A] color values listed in it as a string\n", "df['color'] = df.apply(lambda x: literal_eval(x['color']), axis=1)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
latlngosm_idstation_namechinese_nameopening_datecolorline_name
039.940249116.4563591351272524Agricultural Exhibition Center农业展览馆2008-07-19[0, 146, 188, 255]Line 10
139.955570116.3885075057476994Andelibeijie安德里北街2015-12-26[0, 155, 119, 255]Line 8 (North section)
239.947729116.402067339088654Andingmen安定门1984-09-20[0, 75, 135, 255]Line 2
340.011026116.2639811362259113Anheqiao North安河桥北2009-09-28[0, 140, 149, 255]Line 4
439.967112116.3883985305505996Anhuaqiao安华桥2012-12-30[0, 155, 119, 255]Line 8 (North section)
\n", "
" ], "text/plain": [ " lat lng osm_id station_name \\\n", "0 39.940249 116.456359 1351272524 Agricultural Exhibition Center \n", "1 39.955570 116.388507 5057476994 Andelibeijie \n", "2 39.947729 116.402067 339088654 Andingmen \n", "3 40.011026 116.263981 1362259113 Anheqiao North \n", "4 39.967112 116.388398 5305505996 Anhuaqiao \n", "\n", " chinese_name opening_date color line_name \n", "0 农业展览馆 2008-07-19 [0, 146, 188, 255] Line 10 \n", "1 安德里北街 2015-12-26 [0, 155, 119, 255] Line 8 (North section) \n", "2 安定门 1984-09-20 [0, 75, 135, 255] Line 2 \n", "3 安河桥北 2009-09-28 [0, 140, 149, 255] Line 4 \n", "4 安华桥 2012-12-30 [0, 155, 119, 255] Line 8 (North section) " ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head()" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "851b880d9c7840c6af088c2ad711e95b", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 0, \"latitude\": 39.92295563963415, \"longitude\": 116.3…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Use pydeck's data_utils module to fit a viewport to the central 90% of the data\n", "viewport = data_utils.compute_view(points=df[['lng', 'lat']], view_proportion=0.9)\n", "auto_zoom_map = Deck(layers=None, initial_view_state=viewport)\n", "auto_zoom_map.show()" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "fdf0f0f83c6e47e8bd77db60f17a38a7", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HTML(value='

2019

')" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8436ed25497a47e184341be162f81957", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 0, \"latitude\": 39.92295563963415, \"longitude\": 116.3…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from IPython.core.display import display\n", "import ipywidgets\n", "\n", "year = 2019\n", "\n", "scatterplot = Layer(\n", " 'ScatterplotLayer',\n", " df,\n", " id='scatterplot-layer',\n", " get_radius=500,\n", " get_fill_color='color',\n", " get_position='[lng, lat]')\n", "r = Deck(layers=[scatterplot], initial_view_state=viewport)\n", "\n", "# Create an HTML header to display the year\n", "display_el = ipywidgets.HTML('

{}

'.format(year))\n", "display(display_el)\n", "# Show the current visualization\n", "r.show()" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "import time\n", "for y in range(1971, 2020):\n", " scatterplot.data = df[df['opening_date'] <= str(y)]\n", " year = y\n", " # Reset the header to display the year\n", " display_el.value = '

{}

'.format(year)\n", " r.update()\n", " time.sleep(0.2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using pydeck to manipulate data" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "import pydeck as pdk\n", "\n", "DATA_URL = 'https://api.data.gov.sg/v1/transport/taxi-availability'\n", "COLOR_RANGE = [\n", " [255, 255, 178, 25],\n", " [254, 217, 118, 85],\n", " [254, 178, 76, 127],\n", " [253, 141, 60, 170],\n", " [240, 59, 32, 212],\n", " [189, 0, 38, 255]\n", "]" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import requests\n", "\n", "json = requests.get(DATA_URL).json()\n", "df = pd.DataFrame(json[\"features\"][0][\"geometry\"][\"coordinates\"])\n", "df.columns = ['lng', 'lat']\n", "\n", "viewport = pdk.data_utils.compute_view(df[['lng', 'lat']])\n", "layer = pdk.Layer(\n", " 'ScreenGridLayer',\n", " df,\n", " cell_size_pixels=20,\n", " color_range=COLOR_RANGE,\n", " get_position='[lng, lat]',\n", " pickable=True,\n", " auto_highlight=True)\n", "r = pdk.Deck(layers=[layer], initial_view_state=viewport)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a28aa2a009264ca7b000c781e09e165e", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 0, \"latitude\": 1.3426320730635841, \"longitude\": 103.…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "r.show()\n" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
cellCountcellWeightmaxCellWieghttotalCount
059592322595
\n", "
" ], "text/plain": [ " cellCount cellWeight maxCellWieght totalCount\n", "0 59 59 232 2595" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.DataFrame([r.deck_widget.selected_data])\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plotting massive data sets.ipynb" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.7/site-packages/pandas/core/indexing.py:543: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n", " self.obj[item] = s\n" ] } ], "source": [ "import pandas as pd\n", "all_lidar = pd.concat([\n", " pd.read_csv('https://raw.githubusercontent.com/ajduberstein/kitti_subset/master/kitti_1.csv'),\n", " pd.read_csv('https://raw.githubusercontent.com/ajduberstein/kitti_subset/master/kitti_2.csv'),\n", " pd.read_csv('https://raw.githubusercontent.com/ajduberstein/kitti_subset/master/kitti_3.csv'),\n", " pd.read_csv('https://raw.githubusercontent.com/ajduberstein/kitti_subset/master/kitti_4.csv'),\n", "])\n", "\n", "# Filter to one frame of data\n", "lidar = all_lidar[all_lidar['source'] == 136]\n", "lidar.loc[: , ['x', 'y']] = lidar[['x', 'y']] / 10000" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "4c104563fcc24120a1ee22774cbd1e94", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 120, \"latitude\": -3.0079270065674496e-05, \"longitude…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pydeck as pdk\n", "\n", "\n", "point_cloud = pdk.Layer(\n", " 'PointCloudLayer',\n", " lidar[['x', 'y', 'z']],\n", " get_position='[x, y, z * 10]',\n", " get_normal=[0, 0, 1],\n", " get_color=[255, 0, 100, 200],\n", " pickable=True, \n", " auto_highlight=True,\n", " point_size=1)\n", "\n", "\n", "view_state = pdk.data_utils.compute_view(lidar[['x', 'y']], 0.9)\n", "view_state.max_pitch = 360\n", "view_state.pitch = 80\n", "view_state.bearing = 120\n", "\n", "r = pdk.Deck(\n", " point_cloud,\n", " initial_view_state=view_state,\n", " map_style='')\n", "r.show()" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Press the stop icon to exit\n" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0mframe_buffer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrotate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "import time\n", "from collections import deque\n", "\n", "# Choose a handful of frames to loop through\n", "frame_buffer = deque([42, 56, 81, 95])\n", "print('Press the stop icon to exit')\n", "while True:\n", " current_frame = frame_buffer[0]\n", " lidar = all_lidar[all_lidar['source'] == current_frame]\n", " r.layers[0].get_position = '[x / 10000, y / 10000, z * 10]'\n", " r.layers[0].data = lidar.to_dict(orient='records')\n", " frame_buffer.rotate()\n", " r.update()\n", " time.sleep(0.5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Interacting with other Jupyter widgets.ipynb" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yearlnglatbrightness
01993104.57531.8084
11993104.58331.8084
21993104.59231.8084
31993104.60031.8084
41993104.67531.8084
\n", "
" ], "text/plain": [ " year lng lat brightness\n", "0 1993 104.575 31.808 4\n", "1 1993 104.583 31.808 4\n", "2 1993 104.592 31.808 4\n", "3 1993 104.600 31.808 4\n", "4 1993 104.675 31.808 4" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "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": "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": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e1e26ab1e8d24f408050711bf4fca0e7", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 0, \"latitude\": 31.0, \"longitude\": 104.5, \"maxZoom\": …" ] }, "metadata": {}, "output_type": "display_data" } ], "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", " max_zoom=8,\n", " min_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": 72, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "26cccc78b06543f09cab4322e467bd02", "version_major": 2, "version_minor": 0 }, "text/plain": [ "IntSlider(value=1993, max=2013, min=1993, step=2)" ] }, "metadata": {}, "output_type": "display_data" } ], "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)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tooltip = {\n", " \"html\": \"Elevation Value: {elevationValue}\",\n", " \"style\": {\n", " \"backgroundColor\": \"steelblue\",\n", " \"color\": \"white\"\n", " }\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tooltip" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "86b24465303d4bf087445c1d6071d96d", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": -27.36, \"latitude\": 52.2323, \"longitude\": -1.415, \"m…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pydeck as pdk\n", "\n", "layer = pdk.Layer(\n", " 'HexagonLayer',\n", " UK_ACCIDENTS_DATA,\n", " get_position='[lng, lat]',\n", " auto_highlight=True,\n", " elevation_scale=50,\n", " pickable=True,\n", " elevation_range=[0, 3000],\n", " extruded=True,\n", " coverage=1)\n", "\n", "# Set the viewport location\n", "view_state = pdk.ViewState(\n", " longitude=-1.415,\n", " latitude=52.2323,\n", " zoom=6,\n", " min_zoom=5,\n", " max_zoom=15,\n", " pitch=40.5,\n", " bearing=-27.36)\n", "\n", "# Combined all of it and render a viewport\n", "r = pdk.Deck(\n", " layers=[layer],\n", " initial_view_state=view_state,\n", " tooltip={\n", " 'html': 'Elevation Value: {elevationValue}',\n", " 'style': {\n", " 'color': 'white'\n", " }\n", " }\n", ")\n", "r.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 그냥 텍스트로 하기\n" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7cb21c045ebb49b3b2cd86dcadd929ae", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": -27.36, \"latitude\": 52.2323, \"longitude\": -1.415, \"m…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pydeck as pdk\n", "\n", "layer = pdk.Layer(\n", " 'HexagonLayer',\n", " UK_ACCIDENTS_DATA,\n", " get_position='[lng, lat]',\n", " auto_highlight=True,\n", " elevation_scale=50,\n", " pickable=True,\n", " elevation_range=[0, 3000],\n", " extruded=True,\n", " coverage=1)\n", "\n", "# Set the viewport location\n", "view_state = pdk.ViewState(\n", " longitude=-1.415,\n", " latitude=52.2323,\n", " zoom=6,\n", " min_zoom=5,\n", " max_zoom=15,\n", " pitch=40.5,\n", " bearing=-27.36)\n", "\n", "# Combined all of it and render a viewport\n", "r = pdk.Deck(\n", " layers=[layer],\n", " initial_view_state=view_state,\n", " tooltip = {\n", " \"text\": \"Elevation: {elevationValue}\"\n", " }\n", ")\n", "r.show()\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Tooltip을 그냥 True값만 주기\n" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0c3ea9240e814cefbfa393482288e114", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": -27.36, \"latitude\": 52.2323, \"longitude\": -1.415, \"m…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pydeck as pdk\n", "\n", "layer = pdk.Layer(\n", " 'HexagonLayer',\n", " UK_ACCIDENTS_DATA,\n", " get_position='[lng, lat]',\n", " auto_highlight=True,\n", " elevation_scale=50,\n", " pickable=True,\n", " elevation_range=[0, 3000],\n", " extruded=True,\n", " coverage=1)\n", "\n", "# Set the viewport location\n", "view_state = pdk.ViewState(\n", " longitude=-1.415,\n", " latitude=52.2323,\n", " zoom=6,\n", " min_zoom=5,\n", " max_zoom=15,\n", " pitch=40.5,\n", " bearing=-27.36)\n", "\n", "# Combined all of it and render a viewport\n", "r = pdk.Deck(\n", " layers=[layer],\n", " initial_view_state=view_state,\n", " tooltip=True\n", ")\n", "r.show()" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [], "source": [ "UK_ACCIDENTS_DATA = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv'\n", "\n", "uk_data = pd.read_csv(UK_ACCIDENTS_DATA)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
lnglat
0-0.19846551.505538
1-0.17883851.491836
2-0.20559051.514910
3-0.20832751.514952
4-0.20602251.496572
\n", "
" ], "text/plain": [ " lng lat\n", "0 -0.198465 51.505538\n", "1 -0.178838 51.491836\n", "2 -0.205590 51.514910\n", "3 -0.208327 51.514952\n", "4 -0.206022 51.496572" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "uk_data.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 미국 택시 데이터 시각화" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [], "source": [ "query = \"\"\"\n", "SELECT \n", " *\n", "FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015` \n", "WHERE EXTRACT(MONTH from pickup_datetime) = 1\n", "LIMIT 100000\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 8.49 s, sys: 536 ms, total: 9.03 s\n", "Wall time: 1min\n" ] } ], "source": [ "%%time\n", "taxi_df = pd.read_gbq(query=query, dialect='standard', project_id='geultto')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### GridLayer\n", "- 10만개 데이터" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "4ae7dd6865664406ae47899ad9f7f84c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 0, \"latitude\": 40.7648, \"longitude\": -73.9808, \"maxZ…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "arc_layer = pdk.Layer(\n", " 'GridLayer',\n", " taxi_df,\n", " get_position='[pickup_longitude, pickup_latitude]',\n", " pickable=True, \n", " auto_highlight=True,\n", " tooltip=True\n", ")\n", "\n", "nyc_center = [-73.9808, 40.7648] \n", "view_state = pdk.ViewState(longitude=nyc_center[0], latitude=nyc_center[1], zoom=9)\n", "\n", "r = pdk.Deck(layers=[arc_layer], initial_view_state=view_state)\n", "r.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Arc Layer" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [], "source": [ "zip_code_query = \"\"\"\n", "WITH base_data AS \n", "(\n", " SELECT \n", " nyc_taxi.*, \n", " pickup.zip_code as pickup_zip_code,\n", " pickup.internal_point_lat as pickup_zip_code_lat,\n", " pickup.internal_point_lon as pickup_zip_code_lon,\n", " dropoff.zip_code as dropoff_zip_code,\n", " dropoff.internal_point_lat as dropoff_zip_code_lat,\n", " dropoff.internal_point_lon as dropoff_zip_code_lon\n", " FROM (\n", " SELECT *\n", " FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015`\n", " WHERE \n", " EXTRACT(MONTH from pickup_datetime) = 1\n", " and pickup_latitude <= 90 and pickup_latitude >= -90\n", " and dropoff_latitude <= 90 and dropoff_latitude >= -90\n", " ) AS nyc_taxi\n", " JOIN (\n", " SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon \n", " FROM `bigquery-public-data.geo_us_boundaries.zip_codes`\n", " WHERE state_code='NY'\n", " ) AS pickup \n", " ON ST_CONTAINS(pickup.zip_code_geom, st_geogpoint(pickup_longitude, pickup_latitude))\n", " JOIN (\n", " SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon \n", " FROM `bigquery-public-data.geo_us_boundaries.zip_codes`\n", " WHERE state_code='NY' \n", " ) AS dropoff\n", " ON ST_CONTAINS(dropoff.zip_code_geom, st_geogpoint(dropoff_longitude, dropoff_latitude))\n", " \n", ")\n", "\n", "SELECT \n", " *\n", "FROM base_data \n", "limit 10000\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 1.15 s, sys: 56 ms, total: 1.2 s\n", "Wall time: 42.3 s\n" ] } ], "source": [ "%%time\n", "taxi_df_by_zipcode = pd.read_gbq(query=zip_code_query, dialect='standard', project_id='geultto')" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
vendor_idpickup_datetimedropoff_datetimepassenger_counttrip_distancepickup_longitudepickup_latituderate_codestore_and_fwd_flagdropoff_longitude...tip_amounttolls_amountimp_surchargetotal_amountpickup_zip_codepickup_zip_code_latpickup_zip_code_londropoff_zip_codedropoff_zip_code_latdropoff_zip_code_lon
012015-01-08 23:10:482015-01-08 23:24:5616.00-73.96420340.807423NoneN-73.915398...0.02.440.322.741002740.811408-73.9530601046340.880678-73.906540
122015-01-10 23:41:122015-01-11 00:04:5619.12-73.95011940.771908NoneN-73.845802...5.70.000.335.001007540.773363-73.9562221046140.847394-73.840583
222015-01-01 01:19:222015-01-01 01:33:4732.30-73.93656240.802635NoneN-73.907959...0.00.000.313.301003540.795458-73.9295701045540.814713-73.908590
\n", "

3 rows × 25 columns

\n", "
" ], "text/plain": [ " vendor_id pickup_datetime dropoff_datetime passenger_count \\\n", "0 1 2015-01-08 23:10:48 2015-01-08 23:24:56 1 \n", "1 2 2015-01-10 23:41:12 2015-01-11 00:04:56 1 \n", "2 2 2015-01-01 01:19:22 2015-01-01 01:33:47 3 \n", "\n", " trip_distance pickup_longitude pickup_latitude rate_code \\\n", "0 6.00 -73.964203 40.807423 None \n", "1 9.12 -73.950119 40.771908 None \n", "2 2.30 -73.936562 40.802635 None \n", "\n", " store_and_fwd_flag dropoff_longitude ... tip_amount tolls_amount \\\n", "0 N -73.915398 ... 0.0 2.44 \n", "1 N -73.845802 ... 5.7 0.00 \n", "2 N -73.907959 ... 0.0 0.00 \n", "\n", " imp_surcharge total_amount pickup_zip_code pickup_zip_code_lat \\\n", "0 0.3 22.74 10027 40.811408 \n", "1 0.3 35.00 10075 40.773363 \n", "2 0.3 13.30 10035 40.795458 \n", "\n", " pickup_zip_code_lon dropoff_zip_code dropoff_zip_code_lat \\\n", "0 -73.953060 10463 40.880678 \n", "1 -73.956222 10461 40.847394 \n", "2 -73.929570 10455 40.814713 \n", "\n", " dropoff_zip_code_lon \n", "0 -73.906540 \n", "1 -73.840583 \n", "2 -73.908590 \n", "\n", "[3 rows x 25 columns]" ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "taxi_df_by_zipcode.head(3)" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c9972547a6c2405ca8e931a945076d36", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 0, \"latitude\": 40.7648, \"longitude\": -73.9808, \"maxZ…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\n", "arc_layer = pdk.Layer(\n", " 'ArcLayer',\n", " taxi_df_by_zipcode,\n", " get_source_position='[pickup_zip_code_lon, pickup_zip_code_lat]',\n", " get_target_position='[dropoff_zip_code_lon, dropoff_zip_code_lat]',\n", " get_source_color='[255, 255, 120]', \n", " get_target_color='[255, 0, 0]',\n", " get_widht='elevationValue',\n", " pickable=True, \n", " auto_highlight=True,\n", ")\n", "\n", "nyc_center = [-73.9808, 40.7648] \n", "view_state = pdk.ViewState(longitude=nyc_center[0], latitude=nyc_center[1], zoom=9)\n", "\n", "r = pdk.Deck(layers=[arc_layer], initial_view_state=view_state)\n", "r.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Aggregate " ] }, { "cell_type": "code", "execution_count": 160, "metadata": {}, "outputs": [], "source": [ "agg_query = \"\"\"\n", "WITH base_data AS \n", "(\n", " SELECT \n", " nyc_taxi.*, \n", " pickup.zip_code as pickup_zip_code,\n", " pickup.internal_point_lat as pickup_zip_code_lat,\n", " pickup.internal_point_lon as pickup_zip_code_lon,\n", " dropoff.zip_code as dropoff_zip_code,\n", " dropoff.internal_point_lat as dropoff_zip_code_lat,\n", " dropoff.internal_point_lon as dropoff_zip_code_lon\n", " FROM (\n", " SELECT *\n", " FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015`\n", " WHERE \n", " EXTRACT(MONTH from pickup_datetime) = 1\n", " and pickup_latitude <= 90 and pickup_latitude >= -90\n", " and dropoff_latitude <= 90 and dropoff_latitude >= -90\n", " ) AS nyc_taxi\n", " JOIN (\n", " SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon \n", " FROM `bigquery-public-data.geo_us_boundaries.zip_codes`\n", " WHERE state_code='NY'\n", " ) AS pickup \n", " ON ST_CONTAINS(pickup.zip_code_geom, st_geogpoint(pickup_longitude, pickup_latitude))\n", " JOIN (\n", " SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon \n", " FROM `bigquery-public-data.geo_us_boundaries.zip_codes`\n", " WHERE state_code='NY' \n", " ) AS dropoff\n", " ON ST_CONTAINS(dropoff.zip_code_geom, st_geogpoint(dropoff_longitude, dropoff_latitude))\n", " \n", ")\n", "\n", "SELECT \n", " pickup_zip_code,\n", " pickup_zip_code_lat,\n", " pickup_zip_code_lon,\n", " dropoff_zip_code,\n", " dropoff_zip_code_lat,\n", " dropoff_zip_code_lon,\n", " COUNT(*) AS cnt\n", "FROM base_data \n", "GROUP BY 1,2,3,4,5,6\n", "limit 10000\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 161, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 366 ms, sys: 63.2 ms, total: 429 ms\n", "Wall time: 33.7 s\n" ] } ], "source": [ "%%time\n", "agg_df = pd.read_gbq(query=agg_query, dialect='standard', project_id='geultto')" ] }, { "cell_type": "code", "execution_count": 162, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
pickup_zip_codepickup_zip_code_latpickup_zip_code_londropoff_zip_codedropoff_zip_code_latdropoff_zip_code_loncnt
01135840.760473-73.7963731135840.760473-73.79637335
11003940.830869-73.9362161045640.829886-73.90812120
21142040.673563-73.8178291120140.693700-73.9898592
31141640.684625-73.8495821141940.688638-73.8229425
41123040.622164-73.9651101121840.643477-73.97604266
\n", "
" ], "text/plain": [ " pickup_zip_code pickup_zip_code_lat pickup_zip_code_lon dropoff_zip_code \\\n", "0 11358 40.760473 -73.796373 11358 \n", "1 10039 40.830869 -73.936216 10456 \n", "2 11420 40.673563 -73.817829 11201 \n", "3 11416 40.684625 -73.849582 11419 \n", "4 11230 40.622164 -73.965110 11218 \n", "\n", " dropoff_zip_code_lat dropoff_zip_code_lon cnt \n", "0 40.760473 -73.796373 35 \n", "1 40.829886 -73.908121 20 \n", "2 40.693700 -73.989859 2 \n", "3 40.688638 -73.822942 5 \n", "4 40.643477 -73.976042 66 " ] }, "execution_count": 162, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agg_df.head()" ] }, { "cell_type": "code", "execution_count": 164, "metadata": {}, "outputs": [], "source": [ "agg_df = agg_df.sort_values('cnt', ascending=False)" ] }, { "cell_type": "code", "execution_count": 165, "metadata": {}, "outputs": [], "source": [ "agg_df = agg_df[:100]" ] }, { "cell_type": "code", "execution_count": 226, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ed53f5202676425fb8ab222730748eff", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 0, \"latitude\": 40.7648, \"longitude\": -73.9808, \"maxZ…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\n", "arc_layer = pdk.Layer(\n", " 'ArcLayer',\n", " agg_df,\n", " get_source_position='[pickup_zip_code_lon, pickup_zip_code_lat]',\n", " get_target_position='[dropoff_zip_code_lon, dropoff_zip_code_lat]',\n", " get_source_color='[255, 255, 120]', \n", " get_target_color='[255, 0, 0]',\n", " width_units='meters',\n", " get_width=\"1+10*cnt/500\",\n", " pickable=True, \n", " auto_highlight=True,\n", ")\n", "\n", "nyc_center = [-73.9808, 40.7648] \n", "view_state = pdk.ViewState(longitude=nyc_center[0], latitude=nyc_center[1], zoom=9)\n", "\n", "r = pdk.Deck(layers=[arc_layer], initial_view_state=view_state,\n", " tooltip={\n", " 'html': 'count: {cnt}',\n", " 'style': {\n", " 'color': 'white'\n", " }\n", " }\n", " )\n", "r.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 요일별 위젯" ] }, { "cell_type": "code", "execution_count": 230, "metadata": {}, "outputs": [], "source": [ "agg_query2 = \"\"\"\n", "WITH base_data AS \n", "(\n", " SELECT \n", " nyc_taxi.*, \n", " pickup.zip_code as pickup_zip_code,\n", " pickup.internal_point_lat as pickup_zip_code_lat,\n", " pickup.internal_point_lon as pickup_zip_code_lon,\n", " dropoff.zip_code as dropoff_zip_code,\n", " dropoff.internal_point_lat as dropoff_zip_code_lat,\n", " dropoff.internal_point_lon as dropoff_zip_code_lon\n", " FROM (\n", " SELECT *\n", " FROM `bigquery-public-data.new_york_taxi_trips.tlc_yellow_trips_2015`\n", " WHERE \n", " EXTRACT(MONTH from pickup_datetime) = 1\n", " and pickup_latitude <= 90 and pickup_latitude >= -90\n", " and dropoff_latitude <= 90 and dropoff_latitude >= -90\n", " LIMIT 100000\n", " ) AS nyc_taxi\n", " JOIN (\n", " SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon \n", " FROM `bigquery-public-data.geo_us_boundaries.zip_codes`\n", " WHERE state_code='NY'\n", " ) AS pickup \n", " ON ST_CONTAINS(pickup.zip_code_geom, st_geogpoint(pickup_longitude, pickup_latitude))\n", " JOIN (\n", " SELECT zip_code, state_code, state_name, city, county, zip_code_geom, internal_point_lat, internal_point_lon \n", " FROM `bigquery-public-data.geo_us_boundaries.zip_codes`\n", " WHERE state_code='NY' \n", " ) AS dropoff\n", " ON ST_CONTAINS(dropoff.zip_code_geom, st_geogpoint(dropoff_longitude, dropoff_latitude))\n", " \n", ")\n", "\n", "SELECT \n", " CAST(format_datetime('%u', pickup_datetime) AS INT64) -1 AS weekday,\n", " pickup_zip_code,\n", " pickup_zip_code_lat,\n", " pickup_zip_code_lon,\n", " dropoff_zip_code,\n", " dropoff_zip_code_lat,\n", " dropoff_zip_code_lon,\n", " COUNT(*) AS cnt\n", "FROM base_data \n", "GROUP BY 1,2,3,4,5,6,7\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 242, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 586 ms, sys: 250 ms, total: 836 ms\n", "Wall time: 5.95 s\n" ] } ], "source": [ "%%time\n", "agg_df2 = pd.read_gbq(query=agg_query2, dialect='standard', project_id='geultto')" ] }, { "cell_type": "code", "execution_count": 243, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
weekdaypickup_zip_codepickup_zip_code_latpickup_zip_code_londropoff_zip_codedropoff_zip_code_latdropoff_zip_code_loncnt
061010340.760780-73.9776701002240.758630-73.9679493
141011040.754499-73.9822561002040.758236-73.9788331
231122140.691340-73.9278791122140.691340-73.9278792
331120640.701954-73.9423581122140.691340-73.9278793
461011040.754499-73.9822561001740.752359-73.9724891
\n", "
" ], "text/plain": [ " weekday pickup_zip_code pickup_zip_code_lat pickup_zip_code_lon \\\n", "0 6 10103 40.760780 -73.977670 \n", "1 4 10110 40.754499 -73.982256 \n", "2 3 11221 40.691340 -73.927879 \n", "3 3 11206 40.701954 -73.942358 \n", "4 6 10110 40.754499 -73.982256 \n", "\n", " dropoff_zip_code dropoff_zip_code_lat dropoff_zip_code_lon cnt \n", "0 10022 40.758630 -73.967949 3 \n", "1 10020 40.758236 -73.978833 1 \n", "2 11221 40.691340 -73.927879 2 \n", "3 11221 40.691340 -73.927879 3 \n", "4 10017 40.752359 -73.972489 1 " ] }, "execution_count": 243, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agg_df2.head()" ] }, { "cell_type": "code", "execution_count": 244, "metadata": {}, "outputs": [], "source": [ "default_data = agg_df2[agg_df2['weekday'] == 0].to_dict(orient='records')" ] }, { "cell_type": "code", "execution_count": 250, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "81bfc2bf4c8944e7b685c642338541ce", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DeckGLWidget(json_input='{\"initialViewState\": {\"bearing\": 0, \"latitude\": 40.7648, \"longitude\": -73.9808, \"maxZ…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "arc_layer = pdk.Layer(\n", " 'ArcLayer',\n", " default_data,\n", " get_source_position='[pickup_zip_code_lon, pickup_zip_code_lat]',\n", " get_target_position='[dropoff_zip_code_lon, dropoff_zip_code_lat]',\n", " get_source_color='[255, 255, 120]', \n", " get_target_color='[255, 0, 0]',\n", " width_units='meters',\n", " get_width=\"1+10*cnt/500\",\n", " pickable=True, \n", " auto_highlight=True,\n", ")\n", "\n", "nyc_center = [-73.9808, 40.7648] \n", "view_state = pdk.ViewState(longitude=nyc_center[0], latitude=nyc_center[1], zoom=9)\n", "\n", "r = pdk.Deck(layers=[arc_layer], initial_view_state=view_state,\n", " tooltip={\n", " 'html': 'count: {cnt}',\n", " 'style': {\n", " 'color': 'white'\n", " }\n", " }\n", " )\n", "r.show()\n" ] }, { "cell_type": "code", "execution_count": 246, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "aa7b54f8420f4360ab6069b7ab9324de", "version_major": 2, "version_minor": 0 }, "text/plain": [ "IntSlider(value=0, max=6)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Widget 슬라이더 생성\n", "import ipywidgets as widgets\n", "from IPython.display import display\n", "slider = widgets.IntSlider(0, min=0, max=6, step=1)\n", "\n", "# Widget에서 사용할 함수 정의 \n", "def on_change(v):\n", " results = agg_df2[agg_df2['weekday'] == slider.value].to_dict(orient='records')\n", " arc_layer.data = results\n", " r.update()\n", "\n", "# Deck과 슬라이더 연결\n", "slider.observe(on_change, names='value')\n", "display(slider)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.4" }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }