{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b53a7b12-538d-4459-b82a-a35c8c417849",
   "metadata": {},
   "source": [
    "<img src=\"./images/DLI_Header.png\" width=400/>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae497b71-bc43-471e-8970-88a1878e7cf9",
   "metadata": {},
   "source": [
    "# Fundamentals of Accelerated Data Science # "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a149b6d1-1880-4a5d-9d71-f963d3097aa4",
   "metadata": {},
   "source": [
    "## 06 - Data Visualization ##\n",
    "\n",
    "**Table of Contents**\n",
    "<br>\n",
    "This notebook demonstrates the basics of data visualization for large datasets. This notebook covers the below sections: \n",
    "1. [Data Visualization](#Data-Visualization)\n",
    "2. [Bar Chart](#Bar-Chart)\n",
    "    * [Histogram](#Histogram)\n",
    "    * [Exercise #1 - Bar Chart](#Exercise-#1---Bar-Chart)\n",
    "3. [Scatter Plot](#Scatter-Plot)\n",
    "4. [Line Chart](#Line-Chart)\n",
    "5. [Datashader](#Datashader)\n",
    "    * [Datashader Accelerated by GPU](#Datashader-Accelerated-by-GPU)\n",
    "6. [Interactive Visualization](#Interactive-Visualization)\n",
    "    * [cuxfilter and Dashboard](#cuxfilter-and-Dashboard)\n",
    "6. [Other Libraries](#Other-Libraries)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "39f0f08f-92a2-4bfc-b8bc-5904aa70b5fc",
   "metadata": {},
   "source": [
    "## Data Visualization ##\n",
    "Data visualization is an important part of data science for several reasons: \n",
    "* **Data exploration**: enables data scientists to explore data and quickly identify patterns, trends, and outliers that may not be apparent when looking at raw data in tabular format\n",
    "* **Interpretation**: transforms large and complex datasets into more digestible visual formats, making it easier to comprehend vast amounts of information\n",
    "* **Communication**: helps data scientists communicate complex insights to stakeholders in an easy-to-understand visual format, making data more accessible to non-technical audiences\n",
    "\n",
    "Below is the simple dashboard we will create in this notebook: \n",
    "\n",
    "<p><img src='images/dashboard_1_sample.png' width=720></p>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3300e580-f39d-4147-8ad8-dfbf611ad323",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>sex</th>\n",
       "      <th>county</th>\n",
       "      <th>lat</th>\n",
       "      <th>long</th>\n",
       "      <th>name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.533638</td>\n",
       "      <td>-1.524400</td>\n",
       "      <td>FRANCIS</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.426254</td>\n",
       "      <td>-1.465314</td>\n",
       "      <td>EDWARD</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.555199</td>\n",
       "      <td>-1.496417</td>\n",
       "      <td>TEDDY</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.547909</td>\n",
       "      <td>-1.572342</td>\n",
       "      <td>ANGUS</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.477638</td>\n",
       "      <td>-1.605995</td>\n",
       "      <td>CHARLIE</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   age sex      county        lat      long     name\n",
       "0    0   m  DARLINGTON  54.533638 -1.524400  FRANCIS\n",
       "1    0   m  DARLINGTON  54.426254 -1.465314   EDWARD\n",
       "2    0   m  DARLINGTON  54.555199 -1.496417    TEDDY\n",
       "3    0   m  DARLINGTON  54.547909 -1.572342    ANGUS\n",
       "4    0   m  DARLINGTON  54.477638 -1.605995  CHARLIE"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%load_ext cudf.pandas\n",
    "# DO NOT CHANGE THIS CELL\n",
    "import pandas as pd\n",
    "\n",
    "dtype_dict={\n",
    "    'age': 'int8', \n",
    "    'sex': 'object', \n",
    "    'county': 'object', \n",
    "    'lat': 'float32', \n",
    "    'long': 'float32', \n",
    "    'name': 'object'\n",
    "}\n",
    "        \n",
    "df=pd.read_csv('./data/uk_pop.csv', dtype=dtype_dict)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db58461b-5877-4768-8586-a46765381b6b",
   "metadata": {},
   "source": [
    "## Bar Chart ##\n",
    "Bar charts are used to show and compare categorical data. It represent numercial values with rectangular bars where the length or height of each bar corresponds to the value it represents. \n",
    "\n",
    "Below we show the top 5 counties with the most people. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a0acbf39-b10c-4998-96d7-dde142d844e1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='county'>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 20376 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "df.groupby('county').size().sort_values(ascending=False).head().plot(kind='bar')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b6d94bc-7006-4e73-accb-2649d7dec596",
   "metadata": {},
   "source": [
    "### Histogram ###\n",
    "Bar charts can also be used to show the distribution of data points across different subgroups. This is referred to as a historgram, which is done by counting the number of occurrences (frequency distribution) of each unique value in a dataset. It is used to visualize the shape, center, and spread of a dataset. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b804a51e-63b7-4389-8dd5-3beea5a5950b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='age_bucket'>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 12732 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "bins=[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]\n",
    "df['age_bucket']=pd.cut(df['age'], bins=bins, right=True, include_lowest=True, labels=False)\n",
    "df.groupby('age_bucket').size().plot(kind='bar')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "88341062-8ecc-4264-8c42-bee7ae173c05",
   "metadata": {},
   "source": [
    "### ExerciseExercise #1 - Bar Chart ###\n",
    "We would like to find the distribution of sex in the population. \n",
    "\n",
    "**Instructions**: <br>\n",
    "* Modify the `<FIXME>` only and execute the below cell plot the number of each sex in our dataset. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d0d37093-e329-498d-b748-7fa3fb792303",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='sex'>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 10328 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df.groupby('sex').size().plot(kind='bar')"
   ]
  },
  {
   "cell_type": "raw",
   "id": "b52410a7-777f-4b0a-862f-9fed419d9c79",
   "metadata": {},
   "source": [
    "\n",
    "df.groupby('sex').size().plot(kind='bar')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e49a376-90f6-4ae1-9a47-fae469a5d1da",
   "metadata": {},
   "source": [
    "Click ... for solution. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "676bd687-b998-4724-bda5-e1d68307bb24",
   "metadata": {},
   "source": [
    "## Scatter Plot ##\n",
    "The scatter plot is used to show the relationship between two variables in a dataset. It can also be used to display coordinates of each data point to help identify outliers or clusters. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "e170e8ba-5dbf-428d-b00a-0880d8bdcfad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>sex</th>\n",
       "      <th>county</th>\n",
       "      <th>lat</th>\n",
       "      <th>long</th>\n",
       "      <th>name</th>\n",
       "      <th>age_bucket</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>43400796</th>\n",
       "      <td>40</td>\n",
       "      <td>f</td>\n",
       "      <td>NOTTINGHAMSHIRE</td>\n",
       "      <td>53.054501</td>\n",
       "      <td>-0.943481</td>\n",
       "      <td>ZOYA</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32505888</th>\n",
       "      <td>10</td>\n",
       "      <td>f</td>\n",
       "      <td>NOTTINGHAMSHIRE</td>\n",
       "      <td>52.995071</td>\n",
       "      <td>-0.938463</td>\n",
       "      <td>LINA</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>33512940</th>\n",
       "      <td>13</td>\n",
       "      <td>f</td>\n",
       "      <td>LEICESTERSHIRE</td>\n",
       "      <td>52.967442</td>\n",
       "      <td>-1.849579</td>\n",
       "      <td>TEYANA</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>675372</th>\n",
       "      <td>1</td>\n",
       "      <td>m</td>\n",
       "      <td>SOMERSET</td>\n",
       "      <td>51.138855</td>\n",
       "      <td>-2.919084</td>\n",
       "      <td>HARRISON</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21024733</th>\n",
       "      <td>56</td>\n",
       "      <td>m</td>\n",
       "      <td>BURY</td>\n",
       "      <td>53.628117</td>\n",
       "      <td>-2.325484</td>\n",
       "      <td>JACK</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13618682</th>\n",
       "      <td>36</td>\n",
       "      <td>m</td>\n",
       "      <td>WALTHAM FOREST</td>\n",
       "      <td>51.599720</td>\n",
       "      <td>-0.043070</td>\n",
       "      <td>ETHAN</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11029315</th>\n",
       "      <td>30</td>\n",
       "      <td>m</td>\n",
       "      <td>SALFORD</td>\n",
       "      <td>53.466831</td>\n",
       "      <td>-2.422284</td>\n",
       "      <td>WILLIAM</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>56802229</th>\n",
       "      <td>80</td>\n",
       "      <td>f</td>\n",
       "      <td>NOTTINGHAM</td>\n",
       "      <td>52.972649</td>\n",
       "      <td>-1.233015</td>\n",
       "      <td>ERIN</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29592752</th>\n",
       "      <td>2</td>\n",
       "      <td>f</td>\n",
       "      <td>SALFORD</td>\n",
       "      <td>53.518764</td>\n",
       "      <td>-2.454344</td>\n",
       "      <td>SIRAT</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>33585530</th>\n",
       "      <td>13</td>\n",
       "      <td>f</td>\n",
       "      <td>HERTFORDSHIRE</td>\n",
       "      <td>51.604103</td>\n",
       "      <td>-0.386183</td>\n",
       "      <td>MATILDA</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1000 rows × 7 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "          age sex           county        lat      long      name  age_bucket\n",
       "43400796   40   f  NOTTINGHAMSHIRE  53.054501 -0.943481      ZOYA           3\n",
       "32505888   10   f  NOTTINGHAMSHIRE  52.995071 -0.938463      LINA           0\n",
       "33512940   13   f   LEICESTERSHIRE  52.967442 -1.849579    TEYANA           1\n",
       "675372      1   m         SOMERSET  51.138855 -2.919084  HARRISON           0\n",
       "21024733   56   m             BURY  53.628117 -2.325484      JACK           5\n",
       "...       ...  ..              ...        ...       ...       ...         ...\n",
       "13618682   36   m   WALTHAM FOREST  51.599720 -0.043070     ETHAN           3\n",
       "11029315   30   m          SALFORD  53.466831 -2.422284   WILLIAM           2\n",
       "56802229   80   f       NOTTINGHAM  52.972649 -1.233015      ERIN           7\n",
       "29592752    2   f          SALFORD  53.518764 -2.454344     SIRAT           0\n",
       "33585530   13   f    HERTFORDSHIRE  51.604103 -0.386183   MATILDA           1\n",
       "\n",
       "[1000 rows x 7 columns]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='lat', ylabel='long'>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 44108 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "# sample a very small percentage of the data\n",
    "small_df=df.sample(1000)\n",
    "display(small_df)\n",
    "small_df.plot(kind='scatter', x='lat', y='long')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e0dbf2c-9bbf-4621-bce6-661ede296af9",
   "metadata": {},
   "source": [
    "## Line Chart ##\n",
    "Line charts are good for connecting individual data points to show trends. It's useful for visualizing changes, trends, and patterns over time. \n",
    "\n",
    "The scatter plot doesn't scale well with the number of data points. When the data becomes large, the scatter plot take a long time to complete. Below is line chart of the compute time for different data sizes. \n",
    "\n",
    "<p><img src='images/scatter_time.png', width=480></p>\n",
    "\n",
    "**Note**: Below is the code used to produce this image. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ce18692d-b36f-4275-b056-fd1ec1170abc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# import time\n",
    "# import matplotlib.pyplot as plt\n",
    "\n",
    "# fig, ax=plt.subplots()\n",
    "# exec_times={}\n",
    "\n",
    "# for size in (5*(10**i) for i in range(1, 8)): \n",
    "#     start=time.time()\n",
    "#     df.sample(size).plot(kind='scatter', x='long', y='lat', ax=ax)\n",
    "#     duration=time.time()-start\n",
    "#     exec_times[size]=duration\n",
    "#     ax.clear()\n",
    "\n",
    "# ax.plot(exec_times.keys(), exec_times.values(), marker='o')\n",
    "# ax.set_xscale('log')\n",
    "# ax.set_xlabel('Data Size')\n",
    "# ax.set_ylabel('Execution Time')\n",
    "# ax.set_title(\"Scatter Plot Doesn't Scale Well With Data Size\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "44e65ae7-f223-455f-a463-10f1e193ef64",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'status': 'ok', 'restart': True}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "import IPython\n",
    "app = IPython.Application.instance()\n",
    "app.kernel.do_shutdown(True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b26686d7-fb05-49a0-9006-036810d86160",
   "metadata": {},
   "source": [
    "## Datashader ##\n",
    "[Datashader](https://datashader.org/#) is an open-source Python library for analyzing and visualizing large datasets. Specifically, Datashader is designed to \"rasterize\" or \"aggregate\" datasets into regular grids that can be analyzed further or viewed as images, making it simple and quick to see the properties and patterns of data. \n",
    "\n",
    "Plotting for big data is challenging because rendering a large number of points takes a long time. Datashader shifts the burden of visualization from rendering to computing. Underneath the hood, it turns a long list of (x, y) points into a 2D histogram instead of plotting each point individually. Furthermore, this aggregation can be accelerated through parallel computing. The resulting gridded data structure is then turn into an image, using color to show the magnitude, before being embedding into a plotting program. \n",
    "\n",
    "Datashader generates a plot using a five-step [pipeline](https://datashader.org/getting_started/Pipeline.html): \n",
    "\n",
    "<p><img src='images/ds_pipeline.png' width=720></p>\n",
    "\n",
    "Below we demonstrate how Datashader is used. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a7bd466f-0e40-4b40-bd50-82c9fdc17e2f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "import time\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import datashader as ds\n",
    "import datashader.transfer_functions as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "813eb18b-5234-4a1f-ae05-58bcf8750e9f",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>sex</th>\n",
       "      <th>county</th>\n",
       "      <th>lat</th>\n",
       "      <th>long</th>\n",
       "      <th>name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.533646</td>\n",
       "      <td>-1.524401</td>\n",
       "      <td>FRANCIS</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.426254</td>\n",
       "      <td>-1.465314</td>\n",
       "      <td>EDWARD</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.555199</td>\n",
       "      <td>-1.496417</td>\n",
       "      <td>TEDDY</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.547905</td>\n",
       "      <td>-1.572341</td>\n",
       "      <td>ANGUS</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.477638</td>\n",
       "      <td>-1.605994</td>\n",
       "      <td>CHARLIE</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   age sex      county        lat      long     name\n",
       "0    0   m  DARLINGTON  54.533646 -1.524401  FRANCIS\n",
       "1    0   m  DARLINGTON  54.426254 -1.465314   EDWARD\n",
       "2    0   m  DARLINGTON  54.555199 -1.496417    TEDDY\n",
       "3    0   m  DARLINGTON  54.547905 -1.572341    ANGUS\n",
       "4    0   m  DARLINGTON  54.477638 -1.605994  CHARLIE"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "import pandas as pd\n",
    "\n",
    "dtype_dict={\n",
    "    'age': 'int8', \n",
    "    'sex': 'object', \n",
    "    'county': 'object', \n",
    "    'lat': 'float32', \n",
    "    'long': 'float32', \n",
    "    'name': 'object'\n",
    "}\n",
    "        \n",
    "df=pd.read_csv('./data/uk_pop.csv', dtype=dtype_dict)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5f0085a4-97fa-494f-a525-792f2b65593e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
       "<defs>\n",
       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
       "</symbol>\n",
       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "</symbol>\n",
       "</defs>\n",
       "</svg>\n",
       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
       " *\n",
       " */\n",
       "\n",
       ":root {\n",
       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
       "  --xr-background-color: var(--jp-layout-color0, white);\n",
       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
       "}\n",
       "\n",
       "html[theme=\"dark\"],\n",
       "html[data-theme=\"dark\"],\n",
       "body[data-theme=\"dark\"],\n",
       "body.vscode-dark {\n",
       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
       "  --xr-border-color: #1f1f1f;\n",
       "  --xr-disabled-color: #515151;\n",
       "  --xr-background-color: #111111;\n",
       "  --xr-background-color-row-even: #111111;\n",
       "  --xr-background-color-row-odd: #313131;\n",
       "}\n",
       "\n",
       ".xr-wrap {\n",
       "  display: block !important;\n",
       "  min-width: 300px;\n",
       "  max-width: 700px;\n",
       "}\n",
       "\n",
       ".xr-text-repr-fallback {\n",
       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-header {\n",
       "  padding-top: 6px;\n",
       "  padding-bottom: 6px;\n",
       "  margin-bottom: 4px;\n",
       "  border-bottom: solid 1px var(--xr-border-color);\n",
       "}\n",
       "\n",
       ".xr-header > div,\n",
       ".xr-header > ul {\n",
       "  display: inline;\n",
       "  margin-top: 0;\n",
       "  margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xr-obj-type,\n",
       ".xr-array-name {\n",
       "  margin-left: 2px;\n",
       "  margin-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-obj-type {\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-sections {\n",
       "  padding-left: 0 !important;\n",
       "  display: grid;\n",
       "  grid-template-columns: 150px auto auto 1fr 0 20px 0 20px;\n",
       "}\n",
       "\n",
       ".xr-section-item {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-section-item input {\n",
       "  display: inline-block;\n",
       "  opacity: 0;\n",
       "  height: 0;\n",
       "}\n",
       "\n",
       ".xr-section-item input + label {\n",
       "  color: var(--xr-disabled-color);\n",
       "}\n",
       "\n",
       ".xr-section-item input:enabled + label {\n",
       "  cursor: pointer;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-section-item input:focus + label {\n",
       "  border: 2px solid var(--xr-font-color0);\n",
       "}\n",
       "\n",
       ".xr-section-item input:enabled + label:hover {\n",
       "  color: var(--xr-font-color0);\n",
       "}\n",
       "\n",
       ".xr-section-summary {\n",
       "  grid-column: 1;\n",
       "  color: var(--xr-font-color2);\n",
       "  font-weight: 500;\n",
       "}\n",
       "\n",
       ".xr-section-summary > span {\n",
       "  display: inline-block;\n",
       "  padding-left: 0.5em;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:disabled + label {\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-section-summary-in + label:before {\n",
       "  display: inline-block;\n",
       "  content: \"►\";\n",
       "  font-size: 11px;\n",
       "  width: 15px;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:disabled + label:before {\n",
       "  color: var(--xr-disabled-color);\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked + label:before {\n",
       "  content: \"▼\";\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked + label > span {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-section-summary,\n",
       ".xr-section-inline-details {\n",
       "  padding-top: 4px;\n",
       "  padding-bottom: 4px;\n",
       "}\n",
       "\n",
       ".xr-section-inline-details {\n",
       "  grid-column: 2 / -1;\n",
       "}\n",
       "\n",
       ".xr-section-details {\n",
       "  display: none;\n",
       "  grid-column: 1 / -1;\n",
       "  margin-bottom: 5px;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-array-wrap {\n",
       "  grid-column: 1 / -1;\n",
       "  display: grid;\n",
       "  grid-template-columns: 20px auto;\n",
       "}\n",
       "\n",
       ".xr-array-wrap > label {\n",
       "  grid-column: 1;\n",
       "  vertical-align: top;\n",
       "}\n",
       "\n",
       ".xr-preview {\n",
       "  color: var(--xr-font-color3);\n",
       "}\n",
       "\n",
       ".xr-array-preview,\n",
       ".xr-array-data {\n",
       "  padding: 0 5px !important;\n",
       "  grid-column: 2;\n",
       "}\n",
       "\n",
       ".xr-array-data,\n",
       ".xr-array-in:checked ~ .xr-array-preview {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-array-in:checked ~ .xr-array-data,\n",
       ".xr-array-preview {\n",
       "  display: inline-block;\n",
       "}\n",
       "\n",
       ".xr-dim-list {\n",
       "  display: inline-block !important;\n",
       "  list-style: none;\n",
       "  padding: 0 !important;\n",
       "  margin: 0;\n",
       "}\n",
       "\n",
       ".xr-dim-list li {\n",
       "  display: inline-block;\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "}\n",
       "\n",
       ".xr-dim-list:before {\n",
       "  content: \"(\";\n",
       "}\n",
       "\n",
       ".xr-dim-list:after {\n",
       "  content: \")\";\n",
       "}\n",
       "\n",
       ".xr-dim-list li:not(:last-child):after {\n",
       "  content: \",\";\n",
       "  padding-right: 5px;\n",
       "}\n",
       "\n",
       ".xr-has-index {\n",
       "  font-weight: bold;\n",
       "}\n",
       "\n",
       ".xr-var-list,\n",
       ".xr-var-item {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-var-item > div,\n",
       ".xr-var-item label,\n",
       ".xr-var-item > .xr-var-name span {\n",
       "  background-color: var(--xr-background-color-row-even);\n",
       "  margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xr-var-item > .xr-var-name:hover span {\n",
       "  padding-right: 5px;\n",
       "}\n",
       "\n",
       ".xr-var-list > li:nth-child(odd) > div,\n",
       ".xr-var-list > li:nth-child(odd) > label,\n",
       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
       "  background-color: var(--xr-background-color-row-odd);\n",
       "}\n",
       "\n",
       ".xr-var-name {\n",
       "  grid-column: 1;\n",
       "}\n",
       "\n",
       ".xr-var-dims {\n",
       "  grid-column: 2;\n",
       "}\n",
       "\n",
       ".xr-var-dtype {\n",
       "  grid-column: 3;\n",
       "  text-align: right;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-var-preview {\n",
       "  grid-column: 4;\n",
       "}\n",
       "\n",
       ".xr-index-preview {\n",
       "  grid-column: 2 / 5;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-var-name,\n",
       ".xr-var-dims,\n",
       ".xr-var-dtype,\n",
       ".xr-preview,\n",
       ".xr-attrs dt {\n",
       "  white-space: nowrap;\n",
       "  overflow: hidden;\n",
       "  text-overflow: ellipsis;\n",
       "  padding-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-var-name:hover,\n",
       ".xr-var-dims:hover,\n",
       ".xr-var-dtype:hover,\n",
       ".xr-attrs dt:hover {\n",
       "  overflow: visible;\n",
       "  width: auto;\n",
       "  z-index: 1;\n",
       "}\n",
       "\n",
       ".xr-var-attrs,\n",
       ".xr-var-data,\n",
       ".xr-index-data {\n",
       "  display: none;\n",
       "  background-color: var(--xr-background-color) !important;\n",
       "  padding-bottom: 5px !important;\n",
       "}\n",
       "\n",
       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
       ".xr-var-data-in:checked ~ .xr-var-data,\n",
       ".xr-index-data-in:checked ~ .xr-index-data {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       ".xr-var-data > table {\n",
       "  float: right;\n",
       "}\n",
       "\n",
       ".xr-var-name span,\n",
       ".xr-var-data,\n",
       ".xr-index-name div,\n",
       ".xr-index-data,\n",
       ".xr-attrs {\n",
       "  padding-left: 25px !important;\n",
       "}\n",
       "\n",
       ".xr-attrs,\n",
       ".xr-var-attrs,\n",
       ".xr-var-data,\n",
       ".xr-index-data {\n",
       "  grid-column: 1 / -1;\n",
       "}\n",
       "\n",
       "dl.xr-attrs {\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "  display: grid;\n",
       "  grid-template-columns: 125px auto;\n",
       "}\n",
       "\n",
       ".xr-attrs dt,\n",
       ".xr-attrs dd {\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "  float: left;\n",
       "  padding-right: 10px;\n",
       "  width: auto;\n",
       "}\n",
       "\n",
       ".xr-attrs dt {\n",
       "  font-weight: normal;\n",
       "  grid-column: 1;\n",
       "}\n",
       "\n",
       ".xr-attrs dt:hover span {\n",
       "  display: inline-block;\n",
       "  background: var(--xr-background-color);\n",
       "  padding-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-attrs dd {\n",
       "  grid-column: 2;\n",
       "  white-space: pre-wrap;\n",
       "  word-break: break-all;\n",
       "}\n",
       "\n",
       ".xr-icon-database,\n",
       ".xr-icon-file-text2,\n",
       ".xr-no-icon {\n",
       "  display: inline-block;\n",
       "  vertical-align: middle;\n",
       "  width: 1em;\n",
       "  height: 1.5em !important;\n",
       "  stroke-width: 0;\n",
       "  stroke: currentColor;\n",
       "  fill: currentColor;\n",
       "}\n",
       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray (lat: 600, long: 600)&gt; Size: 1MB\n",
       "array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint32)\n",
       "Coordinates:\n",
       "  * long     (long) float64 5kB -6.361 -6.346 -6.331 ... 2.662 2.677 2.693\n",
       "  * lat      (lat) float64 5kB 49.52 49.54 49.55 49.56 ... 56.23 56.24 56.26\n",
       "Attributes:\n",
       "    x_range:  (-6.368374347686768, 2.7000913619995117)\n",
       "    y_range:  (49.519046783447266, 56.261409759521484)</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'></div><ul class='xr-dim-list'><li><span class='xr-has-index'>lat</span>: 600</li><li><span class='xr-has-index'>long</span>: 600</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-38ad4a13-be2a-4014-9796-a7b8a429e7c7' class='xr-array-in' type='checkbox' checked><label for='section-38ad4a13-be2a-4014-9796-a7b8a429e7c7' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0</span></div><div class='xr-array-data'><pre>array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint32)</pre></div></div></li><li class='xr-section-item'><input id='section-b2d0f400-ad99-4b72-9a60-b550199d41ce' class='xr-section-summary-in' type='checkbox'  checked><label for='section-b2d0f400-ad99-4b72-9a60-b550199d41ce' class='xr-section-summary' >Coordinates: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>long</span></div><div class='xr-var-dims'>(long)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-6.361 -6.346 ... 2.677 2.693</div><input id='attrs-47bbf9b2-97bf-451e-b77e-ffaa44a37566' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-47bbf9b2-97bf-451e-b77e-ffaa44a37566' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-6843a7e4-8a54-49e1-bd9f-ac957153cd5e' class='xr-var-data-in' type='checkbox'><label for='data-6843a7e4-8a54-49e1-bd9f-ac957153cd5e' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([-6.360817, -6.345703, -6.330589, ...,  2.662306,  2.67742 ,  2.692534])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lat</span></div><div class='xr-var-dims'>(lat)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>49.52 49.54 49.55 ... 56.24 56.26</div><input id='attrs-1e0eaaac-c918-4835-bffe-b3569634d3f0' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-1e0eaaac-c918-4835-bffe-b3569634d3f0' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-ad180fb2-d6cb-4a99-814a-ba3d2350e93a' class='xr-var-data-in' type='checkbox'><label for='data-ad180fb2-d6cb-4a99-814a-ba3d2350e93a' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([49.524665, 49.535903, 49.54714 , ..., 56.233317, 56.244554, 56.255791])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-7dacaa94-4ea0-462e-b5dd-2cf35dc95de1' class='xr-section-summary-in' type='checkbox'  ><label for='section-7dacaa94-4ea0-462e-b5dd-2cf35dc95de1' class='xr-section-summary' >Indexes: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-index-name'><div>long</div></div><div class='xr-index-preview'>PandasIndex</div><input type='checkbox' disabled/><label></label><input id='index-f198a6a0-45bd-45f2-8fae-e407c0f43ff2' class='xr-index-data-in' type='checkbox'/><label for='index-f198a6a0-45bd-45f2-8fae-e407c0f43ff2' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([-6.3608172929286955,  -6.345703183412552,  -6.330589073896408,\n",
       "        -6.315474964380265,   -6.30036085486412,  -6.285246745347977,\n",
       "        -6.270132635831833,  -6.255018526315689,  -6.239904416799545,\n",
       "        -6.224790307283402,\n",
       "       ...\n",
       "        2.5565073215961456,  2.5716214311122894,   2.586735540628433,\n",
       "         2.601849650144577,  2.6169637596607207,  2.6320778691768645,\n",
       "        2.6471919786930083,  2.6623060882091525,  2.6774201977252963,\n",
       "          2.69253430724144],\n",
       "      dtype=&#x27;float64&#x27;, name=&#x27;long&#x27;, length=600))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>lat</div></div><div class='xr-index-preview'>PandasIndex</div><input type='checkbox' disabled/><label></label><input id='index-4cbc2d51-9bf4-4702-9d2d-7d3eba0b1084' class='xr-index-data-in' type='checkbox'/><label for='index-4cbc2d51-9bf4-4702-9d2d-7d3eba0b1084' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([ 49.52466541926066,  49.53590269088745,  49.54713996251424,\n",
       "       49.558377234141034, 49.569614505767824, 49.580851777394614,\n",
       "         49.5920890490214,  49.60332632064819,  49.61456359227498,\n",
       "        49.62580086390177,\n",
       "       ...\n",
       "        56.15465567906698,  56.16589295069377,  56.17713022232056,\n",
       "        56.18836749394735, 56.199604765574136, 56.210842037200926,\n",
       "       56.222079308827716, 56.233316580454506, 56.244553852081296,\n",
       "       56.255791123708086],\n",
       "      dtype=&#x27;float64&#x27;, name=&#x27;lat&#x27;, length=600))</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-5cf3d3e0-19d8-4ac7-9c59-ff8c857290e1' class='xr-section-summary-in' type='checkbox'  checked><label for='section-5cf3d3e0-19d8-4ac7-9c59-ff8c857290e1' class='xr-section-summary' >Attributes: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'><dt><span>x_range :</span></dt><dd>(-6.368374347686768, 2.7000913619995117)</dd><dt><span>y_range :</span></dt><dd>(49.519046783447266, 56.261409759521484)</dd></dl></div></li></ul></div></div>"
      ],
      "text/plain": [
       "<xarray.DataArray (lat: 600, long: 600)> Size: 1MB\n",
       "array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint32)\n",
       "Coordinates:\n",
       "  * long     (long) float64 5kB -6.361 -6.346 -6.331 ... 2.662 2.677 2.693\n",
       "  * lat      (lat) float64 5kB 49.52 49.54 49.55 49.56 ... 56.23 56.24 56.26\n",
       "Attributes:\n",
       "    x_range:  (-6.368374347686768, 2.7000913619995117)\n",
       "    y_range:  (49.519046783447266, 56.261409759521484)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Duration: 1.28 seconds\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 90648 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "start=time.time()\n",
    "\n",
    "# get points\n",
    "ds_points_pandas=ds.Canvas().points(df,'long','lat')\n",
    "display(ds_points_pandas)\n",
    "\n",
    "# plot points\n",
    "plt.imshow(tf.shade(ds_points_pandas))\n",
    "\n",
    "print(f'Duration: {round(time.time()-start, 2)} seconds')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09268b18-7e81-46e7-978b-964fe56cda2e",
   "metadata": {},
   "source": [
    "### Datashader Accelerated by GPU ###\n",
    "Datashader can be accelerated by assigning the computation to a GPU. As previously mentioned, the GPU typically has far more (though individually less powerful) cores available than a CPU does, and for highly parallelizable computations like those in Datashader a GPU can typically achieve much faster performance at a given price point than a CPU or distributed set of CPUs can. The DataFrame from cuDF can be used as a replacement for rasterization. The performance benefits are significant since the entire data-processing pipeline is executed on the GPU and there is no bottleneck from data transfer. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "557e70e8-9eaf-4d6b-9048-8a1b433943bd",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>sex</th>\n",
       "      <th>county</th>\n",
       "      <th>lat</th>\n",
       "      <th>long</th>\n",
       "      <th>name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.533638</td>\n",
       "      <td>-1.524400</td>\n",
       "      <td>FRANCIS</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.426254</td>\n",
       "      <td>-1.465314</td>\n",
       "      <td>EDWARD</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.555199</td>\n",
       "      <td>-1.496417</td>\n",
       "      <td>TEDDY</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.547909</td>\n",
       "      <td>-1.572342</td>\n",
       "      <td>ANGUS</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>m</td>\n",
       "      <td>DARLINGTON</td>\n",
       "      <td>54.477638</td>\n",
       "      <td>-1.605995</td>\n",
       "      <td>CHARLIE</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   age sex      county        lat      long     name\n",
       "0    0   m  DARLINGTON  54.533638 -1.524400  FRANCIS\n",
       "1    0   m  DARLINGTON  54.426254 -1.465314   EDWARD\n",
       "2    0   m  DARLINGTON  54.555199 -1.496417    TEDDY\n",
       "3    0   m  DARLINGTON  54.547909 -1.572342    ANGUS\n",
       "4    0   m  DARLINGTON  54.477638 -1.605995  CHARLIE"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "import cudf\n",
    "\n",
    "dtype_dict={\n",
    "    'age': 'int8', \n",
    "    'sex': 'object', \n",
    "    'county': 'object', \n",
    "    'lat': 'float32', \n",
    "    'long': 'float32', \n",
    "    'name': 'object'\n",
    "}\n",
    "        \n",
    "gdf=cudf.read_csv('./data/uk_pop.csv', dtype=dtype_dict)\n",
    "gdf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "6a5b3eb3-40f2-46fb-a45b-5450f45ff398",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
       "<defs>\n",
       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
       "</symbol>\n",
       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
       "</symbol>\n",
       "</defs>\n",
       "</svg>\n",
       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
       " *\n",
       " */\n",
       "\n",
       ":root {\n",
       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
       "  --xr-background-color: var(--jp-layout-color0, white);\n",
       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
       "}\n",
       "\n",
       "html[theme=\"dark\"],\n",
       "html[data-theme=\"dark\"],\n",
       "body[data-theme=\"dark\"],\n",
       "body.vscode-dark {\n",
       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
       "  --xr-border-color: #1f1f1f;\n",
       "  --xr-disabled-color: #515151;\n",
       "  --xr-background-color: #111111;\n",
       "  --xr-background-color-row-even: #111111;\n",
       "  --xr-background-color-row-odd: #313131;\n",
       "}\n",
       "\n",
       ".xr-wrap {\n",
       "  display: block !important;\n",
       "  min-width: 300px;\n",
       "  max-width: 700px;\n",
       "}\n",
       "\n",
       ".xr-text-repr-fallback {\n",
       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-header {\n",
       "  padding-top: 6px;\n",
       "  padding-bottom: 6px;\n",
       "  margin-bottom: 4px;\n",
       "  border-bottom: solid 1px var(--xr-border-color);\n",
       "}\n",
       "\n",
       ".xr-header > div,\n",
       ".xr-header > ul {\n",
       "  display: inline;\n",
       "  margin-top: 0;\n",
       "  margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xr-obj-type,\n",
       ".xr-array-name {\n",
       "  margin-left: 2px;\n",
       "  margin-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-obj-type {\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-sections {\n",
       "  padding-left: 0 !important;\n",
       "  display: grid;\n",
       "  grid-template-columns: 150px auto auto 1fr 0 20px 0 20px;\n",
       "}\n",
       "\n",
       ".xr-section-item {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-section-item input {\n",
       "  display: inline-block;\n",
       "  opacity: 0;\n",
       "  height: 0;\n",
       "}\n",
       "\n",
       ".xr-section-item input + label {\n",
       "  color: var(--xr-disabled-color);\n",
       "}\n",
       "\n",
       ".xr-section-item input:enabled + label {\n",
       "  cursor: pointer;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-section-item input:focus + label {\n",
       "  border: 2px solid var(--xr-font-color0);\n",
       "}\n",
       "\n",
       ".xr-section-item input:enabled + label:hover {\n",
       "  color: var(--xr-font-color0);\n",
       "}\n",
       "\n",
       ".xr-section-summary {\n",
       "  grid-column: 1;\n",
       "  color: var(--xr-font-color2);\n",
       "  font-weight: 500;\n",
       "}\n",
       "\n",
       ".xr-section-summary > span {\n",
       "  display: inline-block;\n",
       "  padding-left: 0.5em;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:disabled + label {\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-section-summary-in + label:before {\n",
       "  display: inline-block;\n",
       "  content: \"►\";\n",
       "  font-size: 11px;\n",
       "  width: 15px;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:disabled + label:before {\n",
       "  color: var(--xr-disabled-color);\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked + label:before {\n",
       "  content: \"▼\";\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked + label > span {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-section-summary,\n",
       ".xr-section-inline-details {\n",
       "  padding-top: 4px;\n",
       "  padding-bottom: 4px;\n",
       "}\n",
       "\n",
       ".xr-section-inline-details {\n",
       "  grid-column: 2 / -1;\n",
       "}\n",
       "\n",
       ".xr-section-details {\n",
       "  display: none;\n",
       "  grid-column: 1 / -1;\n",
       "  margin-bottom: 5px;\n",
       "}\n",
       "\n",
       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-array-wrap {\n",
       "  grid-column: 1 / -1;\n",
       "  display: grid;\n",
       "  grid-template-columns: 20px auto;\n",
       "}\n",
       "\n",
       ".xr-array-wrap > label {\n",
       "  grid-column: 1;\n",
       "  vertical-align: top;\n",
       "}\n",
       "\n",
       ".xr-preview {\n",
       "  color: var(--xr-font-color3);\n",
       "}\n",
       "\n",
       ".xr-array-preview,\n",
       ".xr-array-data {\n",
       "  padding: 0 5px !important;\n",
       "  grid-column: 2;\n",
       "}\n",
       "\n",
       ".xr-array-data,\n",
       ".xr-array-in:checked ~ .xr-array-preview {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       ".xr-array-in:checked ~ .xr-array-data,\n",
       ".xr-array-preview {\n",
       "  display: inline-block;\n",
       "}\n",
       "\n",
       ".xr-dim-list {\n",
       "  display: inline-block !important;\n",
       "  list-style: none;\n",
       "  padding: 0 !important;\n",
       "  margin: 0;\n",
       "}\n",
       "\n",
       ".xr-dim-list li {\n",
       "  display: inline-block;\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "}\n",
       "\n",
       ".xr-dim-list:before {\n",
       "  content: \"(\";\n",
       "}\n",
       "\n",
       ".xr-dim-list:after {\n",
       "  content: \")\";\n",
       "}\n",
       "\n",
       ".xr-dim-list li:not(:last-child):after {\n",
       "  content: \",\";\n",
       "  padding-right: 5px;\n",
       "}\n",
       "\n",
       ".xr-has-index {\n",
       "  font-weight: bold;\n",
       "}\n",
       "\n",
       ".xr-var-list,\n",
       ".xr-var-item {\n",
       "  display: contents;\n",
       "}\n",
       "\n",
       ".xr-var-item > div,\n",
       ".xr-var-item label,\n",
       ".xr-var-item > .xr-var-name span {\n",
       "  background-color: var(--xr-background-color-row-even);\n",
       "  margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xr-var-item > .xr-var-name:hover span {\n",
       "  padding-right: 5px;\n",
       "}\n",
       "\n",
       ".xr-var-list > li:nth-child(odd) > div,\n",
       ".xr-var-list > li:nth-child(odd) > label,\n",
       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
       "  background-color: var(--xr-background-color-row-odd);\n",
       "}\n",
       "\n",
       ".xr-var-name {\n",
       "  grid-column: 1;\n",
       "}\n",
       "\n",
       ".xr-var-dims {\n",
       "  grid-column: 2;\n",
       "}\n",
       "\n",
       ".xr-var-dtype {\n",
       "  grid-column: 3;\n",
       "  text-align: right;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-var-preview {\n",
       "  grid-column: 4;\n",
       "}\n",
       "\n",
       ".xr-index-preview {\n",
       "  grid-column: 2 / 5;\n",
       "  color: var(--xr-font-color2);\n",
       "}\n",
       "\n",
       ".xr-var-name,\n",
       ".xr-var-dims,\n",
       ".xr-var-dtype,\n",
       ".xr-preview,\n",
       ".xr-attrs dt {\n",
       "  white-space: nowrap;\n",
       "  overflow: hidden;\n",
       "  text-overflow: ellipsis;\n",
       "  padding-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-var-name:hover,\n",
       ".xr-var-dims:hover,\n",
       ".xr-var-dtype:hover,\n",
       ".xr-attrs dt:hover {\n",
       "  overflow: visible;\n",
       "  width: auto;\n",
       "  z-index: 1;\n",
       "}\n",
       "\n",
       ".xr-var-attrs,\n",
       ".xr-var-data,\n",
       ".xr-index-data {\n",
       "  display: none;\n",
       "  background-color: var(--xr-background-color) !important;\n",
       "  padding-bottom: 5px !important;\n",
       "}\n",
       "\n",
       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
       ".xr-var-data-in:checked ~ .xr-var-data,\n",
       ".xr-index-data-in:checked ~ .xr-index-data {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       ".xr-var-data > table {\n",
       "  float: right;\n",
       "}\n",
       "\n",
       ".xr-var-name span,\n",
       ".xr-var-data,\n",
       ".xr-index-name div,\n",
       ".xr-index-data,\n",
       ".xr-attrs {\n",
       "  padding-left: 25px !important;\n",
       "}\n",
       "\n",
       ".xr-attrs,\n",
       ".xr-var-attrs,\n",
       ".xr-var-data,\n",
       ".xr-index-data {\n",
       "  grid-column: 1 / -1;\n",
       "}\n",
       "\n",
       "dl.xr-attrs {\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "  display: grid;\n",
       "  grid-template-columns: 125px auto;\n",
       "}\n",
       "\n",
       ".xr-attrs dt,\n",
       ".xr-attrs dd {\n",
       "  padding: 0;\n",
       "  margin: 0;\n",
       "  float: left;\n",
       "  padding-right: 10px;\n",
       "  width: auto;\n",
       "}\n",
       "\n",
       ".xr-attrs dt {\n",
       "  font-weight: normal;\n",
       "  grid-column: 1;\n",
       "}\n",
       "\n",
       ".xr-attrs dt:hover span {\n",
       "  display: inline-block;\n",
       "  background: var(--xr-background-color);\n",
       "  padding-right: 10px;\n",
       "}\n",
       "\n",
       ".xr-attrs dd {\n",
       "  grid-column: 2;\n",
       "  white-space: pre-wrap;\n",
       "  word-break: break-all;\n",
       "}\n",
       "\n",
       ".xr-icon-database,\n",
       ".xr-icon-file-text2,\n",
       ".xr-no-icon {\n",
       "  display: inline-block;\n",
       "  vertical-align: middle;\n",
       "  width: 1em;\n",
       "  height: 1.5em !important;\n",
       "  stroke-width: 0;\n",
       "  stroke: currentColor;\n",
       "  fill: currentColor;\n",
       "}\n",
       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray (lat: 600, long: 600)&gt; Size: 1MB\n",
       "array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint32)\n",
       "Coordinates:\n",
       "  * long     (long) float64 5kB -6.361 -6.346 -6.331 ... 2.662 2.677 2.693\n",
       "  * lat      (lat) float64 5kB 49.52 49.54 49.55 49.56 ... 56.23 56.24 56.26\n",
       "Attributes:\n",
       "    x_range:  (-6.368374, 2.7000911)\n",
       "    y_range:  (49.51904, 56.26141)</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'></div><ul class='xr-dim-list'><li><span class='xr-has-index'>lat</span>: 600</li><li><span class='xr-has-index'>long</span>: 600</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-945788d9-b29b-4ed5-ad98-9267b2163249' class='xr-array-in' type='checkbox' checked><label for='section-945788d9-b29b-4ed5-ad98-9267b2163249' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>array([[0, 0, 0, ..., 0, 0, 0],        [0, 0, 0, ..., 0, 0, 0],    ...</span></div><div class='xr-array-data'><pre>array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint32)</pre></div></div></li><li class='xr-section-item'><input id='section-19532a3b-9340-4156-babe-f5a667e58f7e' class='xr-section-summary-in' type='checkbox'  checked><label for='section-19532a3b-9340-4156-babe-f5a667e58f7e' class='xr-section-summary' >Coordinates: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>long</span></div><div class='xr-var-dims'>(long)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-6.361 -6.346 ... 2.677 2.693</div><input id='attrs-2839a712-862c-4124-a521-07ba5766be66' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-2839a712-862c-4124-a521-07ba5766be66' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-0cad6a62-f973-40d4-a2d5-0b8b6e8c450a' class='xr-var-data-in' type='checkbox'><label for='data-0cad6a62-f973-40d4-a2d5-0b8b6e8c450a' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([-6.360817, -6.345703, -6.330589, ...,  2.662306,  2.67742 ,  2.692534])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>lat</span></div><div class='xr-var-dims'>(lat)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>49.52 49.54 49.55 ... 56.24 56.26</div><input id='attrs-f663816a-ca17-4de7-b8aa-9047cc1c46c1' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-f663816a-ca17-4de7-b8aa-9047cc1c46c1' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-8cd8d2d3-0515-4aff-9afa-1ba8cf2664f4' class='xr-var-data-in' type='checkbox'><label for='data-8cd8d2d3-0515-4aff-9afa-1ba8cf2664f4' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([49.524658, 49.535895, 49.547132, ..., 56.233317, 56.244554, 56.255791])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-074060f9-0a33-4632-b1b5-6891bdfa35f9' class='xr-section-summary-in' type='checkbox'  ><label for='section-074060f9-0a33-4632-b1b5-6891bdfa35f9' class='xr-section-summary' >Indexes: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-index-name'><div>long</div></div><div class='xr-index-preview'>PandasIndex</div><input type='checkbox' disabled/><label></label><input id='index-2775c2ec-69e2-46c2-9953-0144585bdef5' class='xr-index-data-in' type='checkbox'/><label for='index-2775c2ec-69e2-46c2-9953-0144585bdef5' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([-6.360816816687584, -6.345702708363533, -6.330588600039482,\n",
       "       -6.315474491715431,  -6.30036038339138,  -6.28524627506733,\n",
       "       -6.270132166743279, -6.255018058419227, -6.239903950095177,\n",
       "       -6.224789841771126,\n",
       "       ...\n",
       "       2.5565070945024484, 2.5716212028264995,   2.58673531115055,\n",
       "       2.6018494194746014,  2.616963527798652,  2.632077636122703,\n",
       "        2.647191744446754,  2.662305852770805, 2.6774199610948557,\n",
       "        2.692534069418907],\n",
       "      dtype=&#x27;float64&#x27;, name=&#x27;long&#x27;, length=600))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>lat</div></div><div class='xr-index-preview'>PandasIndex</div><input type='checkbox' disabled/><label></label><input id='index-f9ceb9e7-e11d-45d4-a947-29cc1420937f' class='xr-index-data-in' type='checkbox'/><label for='index-f9ceb9e7-e11d-45d4-a947-29cc1420937f' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([ 49.52465779622396,  49.53589508056641, 49.547132364908855,\n",
       "       49.558369649251304, 49.569606933593754,   49.5808442179362,\n",
       "       49.592081502278646, 49.603318786621095, 49.614556070963545,\n",
       "       49.625793355305994,\n",
       "       ...\n",
       "        56.15465555826823,  56.16589284261068,  56.17713012695313,\n",
       "        56.18836741129557,  56.19960469563802,  56.21084197998047,\n",
       "        56.22207926432292, 56.233316548665364, 56.244553833007814,\n",
       "        56.25579111735026],\n",
       "      dtype=&#x27;float64&#x27;, name=&#x27;lat&#x27;, length=600))</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-4196ce8d-3825-470c-8796-d93602260d38' class='xr-section-summary-in' type='checkbox'  checked><label for='section-4196ce8d-3825-470c-8796-d93602260d38' class='xr-section-summary' >Attributes: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'><dt><span>x_range :</span></dt><dd>(-6.368374, 2.7000911)</dd><dt><span>y_range :</span></dt><dd>(49.51904, 56.26141)</dd></dl></div></li></ul></div></div>"
      ],
      "text/plain": [
       "<xarray.DataArray (lat: 600, long: 600)> Size: 1MB\n",
       "array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint32)\n",
       "Coordinates:\n",
       "  * long     (long) float64 5kB -6.361 -6.346 -6.331 ... 2.662 2.677 2.693\n",
       "  * lat      (lat) float64 5kB 49.52 49.54 49.55 49.56 ... 56.23 56.24 56.26\n",
       "Attributes:\n",
       "    x_range:  (-6.368374, 2.7000911)\n",
       "    y_range:  (49.51904, 56.26141)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Duration: 0.08 seconds\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 90520 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# DO NOT CHANGE THIS CELL\n",
    "start=time.time()\n",
    "\n",
    "# get points\n",
    "ds_points_cudf=ds.Canvas().points(gdf,'long','lat')\n",
    "display(ds_points_cudf)\n",
    "\n",
    "# plot points\n",
    "plt.imshow(tf.shade(ds_points_cudf))\n",
    "\n",
    "print(f'Duration: {round(time.time()-start, 2)} seconds')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98b1c4a7-9b60-4970-859f-b9ffedd4315c",
   "metadata": {},
   "source": [
    "**Note**: Please re-execute the above cell if it took more than a few seconds for the more accurate compute time. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e664fb6-7482-49d0-bc60-efaefd2184d3",
   "metadata": {},
   "source": [
    "## Interactive Visualization ##\n",
    "Data visualization is crucial in data science as it bridges the gap between complex data and human understanding, making insights more accessible, actionable, and impactful throughout the data science process. Bringing interactivity in data visualization further enables: \n",
    "* **Discovery**: enables discovery of hidden patterns, trends, and outliers that may not be apparant in static visualizations\n",
    "* **Enhanced understanding**: allows users to view data from multiple perspective and levels of detail\n",
    "* **Customization**: provides the ability to rapidly filter, sort, and aggregate data, leading to a more impactful presentation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "084911da-fb99-43e8-bff6-e11f032b4c9e",
   "metadata": {},
   "source": [
    "### cuxfilter and Dashboard ###\n",
    "cuxfilter enables GPU accelerated cross-filtering dashboards, which is ideal for multi-chart exploratory data analysis. Cross-filtering lets users interact with one chart and apply that interaction as a filter to other charts in the dashboard. \n",
    "\n",
    "cuxfilter acts as a connector library, which provides the connections between different visualization libraries and a GPU DataFrame without much hassle. This also allows users to use charts from different libraries in a single dashboard, while also providing the interaction. Currently, cuxfilter supports: \n",
    "* [Bokeh](https://bokeh.org/) Charts\n",
    "    * Bar chart\n",
    "    * Line chart\n",
    "    * Choropleth\n",
    "* [Datashader](https://datashader.org/) Charts\n",
    "    * Line\n",
    "    * Scatter\n",
    "* [Panel Widgets](https://panel.holoviz.org/api/panel.widgets.html)\n",
    "    * Range\n",
    "    * Float\n",
    "    * Int\n",
    "    * Dropdown\n",
    "    * Multiselect"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f1777e6a-a717-49d4-9b38-e855d987ca92",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cuxfilter as cxf\n",
    "\n",
    "# factorize county for multiselect widget\n",
    "gdf['county'], county_names = gdf['county'].factorize()\n",
    "county_map = dict(zip(list(range(len(county_names))), county_names.to_arrow()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "680c06ed-f8c6-4de5-b366-78f0c1092aeb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create cuxfilter DataFrame\n",
    "cxf_data = cxf.DataFrame.from_dataframe(gdf)\n",
    "\n",
    "# create Datashader scatter plot\n",
    "scatter_chart = cxf.charts.scatter(x='long', y='lat')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c2d8a372-6e14-442c-a61d-f5ea44fc7f6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create Bokeh bar charts\n",
    "chart_3=cxf.charts.bar('age')\n",
    "chart_2=cxf.charts.bar('sex')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "fb700802-45b8-4558-b58b-c2a96cfda78b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# define layout\n",
    "layout_array=[[1, 2, 2], \n",
    "              [3, 2, 2]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "a7964e08-1e77-4431-83b1-ef0e798d32f5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script type=\"esms-options\">{\"shimMode\": true}</script><style>*[data-root-id],\n",
       "*[data-root-id] > * {\n",
       "  box-sizing: border-box;\n",
       "  font-family: var(--jp-ui-font-family);\n",
       "  font-size: var(--jp-ui-font-size1);\n",
       "  color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
       "}\n",
       "\n",
       "/* Override VSCode background color */\n",
       ".cell-output-ipywidget-background:has(\n",
       "    > .cell-output-ipywidget-background > .lm-Widget > *[data-root-id]\n",
       "  ),\n",
       ".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
       "  background-color: transparent !important;\n",
       "}\n",
       "</style>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": "(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  const force = true;\n  const py_version = '3.6.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n  const reloading = false;\n  const Bokeh = root.Bokeh;\n\n  // Set a timeout for this load but only if we are not already initializing\n  if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) {\n        if (callback != null)\n          callback();\n      });\n    } finally {\n      delete root._bokeh_onload_callbacks;\n    }\n    console.debug(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n    if (css_urls == null) css_urls = [];\n    if (js_urls == null) js_urls = [];\n    if (js_modules == null) js_modules = [];\n    if (js_exports == null) js_exports = {};\n\n    root._bokeh_onload_callbacks.push(callback);\n\n    if (root._bokeh_is_loading > 0) {\n      // Don't load bokeh if it is still initializing\n      console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n      // There is nothing to load\n      run_callbacks();\n      return null;\n    }\n\n    function on_load() {\n      root._bokeh_is_loading--;\n      if (root._bokeh_is_loading === 0) {\n        console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n        run_callbacks()\n      }\n    }\n    window._bokeh_on_load = on_load\n\n    function on_error(e) {\n      const src_el = e.srcElement\n      console.error(\"failed to load \" + (src_el.href || src_el.src));\n    }\n\n    const skip = [];\n    if (window.requirejs) {\n      window.requirejs.config({'packages': {}, 'paths': {'h3': 'https://cdn.jsdelivr.net/npm/h3-js@4.1.0/dist/h3-js.umd', 'deck-gl': 'https://cdn.jsdelivr.net/npm/deck.gl@9.0.20/dist.min', 'deck-json': 'https://cdn.jsdelivr.net/npm/@deck.gl/json@9.0.20/dist.min', 'loader-csv': 'https://cdn.jsdelivr.net/npm/@loaders.gl/csv@4.2.2/dist/dist.min', 'loader-json': 'https://cdn.jsdelivr.net/npm/@loaders.gl/json@4.2.2/dist/dist.min', 'loader-tiles': 'https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@4.2.2/dist/dist.min', 'mapbox-gl': 'https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl', 'carto': 'https://cdn.jsdelivr.net/npm/@deck.gl/carto@^9.0.20/dist.min'}, 'shim': {'deck-json': {'deps': ['deck-gl']}, 'deck-gl': {'deps': ['h3']}}});\n      require([\"h3\"], function(h3) {\n        window.h3 = h3\n        on_load()\n      })\n      require([\"deck-gl\"], function(deck) {\n        window.deck = deck\n        on_load()\n      })\n      require([\"deck-json\"], function() {\n        on_load()\n      })\n      require([\"loader-csv\"], function() {\n        on_load()\n      })\n      require([\"loader-json\"], function() {\n        on_load()\n      })\n      require([\"loader-tiles\"], function() {\n        on_load()\n      })\n      require([\"mapbox-gl\"], function(mapboxgl) {\n        window.mapboxgl = mapboxgl\n        on_load()\n      })\n      require([\"carto\"], function() {\n        on_load()\n      })\n      root._bokeh_is_loading = css_urls.length + 8;\n    } else {\n      root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n    }\n\n    const existing_stylesheets = []\n    const links = document.getElementsByTagName('link')\n    for (let i = 0; i < links.length; i++) {\n      const link = links[i]\n      if (link.href != null) {\n        existing_stylesheets.push(link.href)\n      }\n    }\n    for (let i = 0; i < css_urls.length; i++) {\n      const url = css_urls[i];\n      const escaped = encodeURI(url)\n      if (existing_stylesheets.indexOf(escaped) !== -1) {\n        on_load()\n        continue;\n      }\n      const element = document.createElement(\"link\");\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.rel = \"stylesheet\";\n      element.type = \"text/css\";\n      element.href = url;\n      console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n      document.body.appendChild(element);\n    }    if (((window.deck !== undefined) && (!(window.deck instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(encodeURI(urls[i]))\n      }\n    }    if (((window.mapboxgl !== undefined) && (!(window.mapboxgl instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(encodeURI(urls[i]))\n      }\n    }    var existing_scripts = []\n    const scripts = document.getElementsByTagName('script')\n    for (let i = 0; i < scripts.length; i++) {\n      var script = scripts[i]\n      if (script.src != null) {\n        existing_scripts.push(script.src)\n      }\n    }\n    for (let i = 0; i < js_urls.length; i++) {\n      const url = js_urls[i];\n      const escaped = encodeURI(url)\n      if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n        if (!window.requirejs) {\n          on_load();\n        }\n        continue;\n      }\n      const element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.async = false;\n      element.src = url;\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n    for (let i = 0; i < js_modules.length; i++) {\n      const url = js_modules[i];\n      const escaped = encodeURI(url)\n      if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n        if (!window.requirejs) {\n          on_load();\n        }\n        continue;\n      }\n      var element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.async = false;\n      element.src = url;\n      element.type = \"module\";\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n    for (const name in js_exports) {\n      const url = js_exports[name];\n      const escaped = encodeURI(url)\n      if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n        if (!window.requirejs) {\n          on_load();\n        }\n        continue;\n      }\n      var element = document.createElement('script');\n      element.onerror = on_error;\n      element.async = false;\n      element.type = \"module\";\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      element.textContent = `\n      import ${name} from \"${url}\"\n      window.${name} = ${name}\n      window._bokeh_on_load()\n      `\n      document.head.appendChild(element);\n    }\n    if (!js_urls.length && !js_modules.length) {\n      on_load()\n    }\n  };\n\n  function inject_raw_css(css) {\n    const element = document.createElement(\"style\");\n    element.appendChild(document.createTextNode(css));\n    document.body.appendChild(element);\n  }\n\n  const js_urls = [\"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.6.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.6.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/panel.min.js\"];\n  const js_modules = [];\n  const js_exports = {};\n  const css_urls = [\"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.css?v=1.5.4\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/maplibre-gl@4.4.1/dist/maplibre-gl.css?v=1.5.4\"];\n  const inline_js = [    function(Bokeh) {\n      inject_raw_css(\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\");\n    },    function(Bokeh) {\n      inject_raw_css(\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\");\n    },    function(Bokeh) {\n      inject_raw_css(\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\");\n    },    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\n    function(Bokeh) {\n      (function(root, factory) {\n          factory(root[\"Bokeh\"]);\n      })(this, function(Bokeh) {\n        let define;\n        return (function outer(modules, entry) {\n        if (Bokeh != null) {\n          return Bokeh.register_plugin(modules, entry);\n        } else {\n          throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n        }\n      })\n      ({\n        \"custom/main\": function(require, module, exports) {\n          const models = {\n            \"CustomInspectTool\": require(\"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\").CustomInspectTool\n          };\n          require(\"base\").register_models(models);\n          module.exports = models;\n        },\n        \"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\": function(require, module, exports) {\n      \"use strict\";\n      var _a;\n      Object.defineProperty(exports, \"__esModule\", { value: true });\n      exports.CustomInspectTool = exports.CustomInspectToolView = void 0;\n      const inspect_tool_1 = require(\"models/tools/inspectors/inspect_tool\");\n      class CustomInspectToolView extends inspect_tool_1.InspectToolView {\n          connect_signals() {\n              super.connect_signals();\n              this.on_change([this.model.properties.active], () => {\n                  this.model._active = this.model.active;\n              });\n          }\n      }\n      exports.CustomInspectToolView = CustomInspectToolView;\n      CustomInspectToolView.__name__ = \"CustomInspectToolView\";\n      class CustomInspectTool extends inspect_tool_1.InspectTool {\n          constructor(attrs) {\n              super(attrs);\n          }\n      }\n      exports.CustomInspectTool = CustomInspectTool;\n      _a = CustomInspectTool;\n      CustomInspectTool.__name__ = \"CustomInspectTool\";\n      (() => {\n          _a.prototype.default_view = CustomInspectToolView;\n          _a.define(({ Boolean }) => ({\n              _active: [Boolean, true]\n          }));\n          _a.register_alias(\"customInspect\", () => new _a());\n      })();\n      //# sourceMappingURL=graph_inspect_widget.py:CustomInspectTool.js.map\n      }\n      }, \"custom/main\");\n      ;\n      });\n\n    },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n  ];\n\n  function run_inline_js() {\n    if ((root.Bokeh !== undefined) || (force === true)) {\n      for (let i = 0; i < inline_js.length; i++) {\n        try {\n          inline_js[i].call(root, root.Bokeh);\n        } catch(e) {\n          if (!reloading) {\n            throw e;\n          }\n        }\n      }\n      // Cache old bokeh versions\n      if (Bokeh != undefined && !reloading) {\n        var NewBokeh = root.Bokeh;\n        if (Bokeh.versions === undefined) {\n          Bokeh.versions = new Map();\n        }\n        if (NewBokeh.version !== Bokeh.version) {\n          Bokeh.versions.set(NewBokeh.version, NewBokeh)\n        }\n        root.Bokeh = Bokeh;\n      }\n    } else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    }\n    root._bokeh_is_initializing = false\n  }\n\n  function load_or_wait() {\n    // Implement a backoff loop that tries to ensure we do not load multiple\n    // versions of Bokeh and its dependencies at the same time.\n    // In recent versions we use the root._bokeh_is_initializing flag\n    // to determine whether there is an ongoing attempt to initialize\n    // bokeh, however for backward compatibility we also try to ensure\n    // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n    // before older versions are fully initialized.\n    if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n      // If the timeout and bokeh was not successfully loaded we reset\n      // everything and try loading again\n      root._bokeh_timeout = Date.now() + 5000;\n      root._bokeh_is_initializing = false;\n      root._bokeh_onload_callbacks = undefined;\n      root._bokeh_is_loading = 0\n      console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n      load_or_wait();\n    } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n      setTimeout(load_or_wait, 100);\n    } else {\n      root._bokeh_is_initializing = true\n      root._bokeh_onload_callbacks = []\n      const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n      if (!reloading && !bokeh_loaded) {\n        if (root.Bokeh) {\n          root.Bokeh = undefined;\n        }\n        console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n      }\n      load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n        console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n        run_inline_js();\n      });\n    }\n  }\n  // Give older versions of the autoload script a head-start to ensure\n  // they initialize before we start loading newer version.\n  setTimeout(load_or_wait, 100)\n}(window));",
      "application/vnd.holoviews_load.v0+json": ""
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n  window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n    function JupyterCommManager() {\n    }\n\n    JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n      if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n        comm_manager.register_target(comm_id, function(comm) {\n          comm.on_msg(msg_handler);\n        });\n      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n        window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n          comm.onMsg = msg_handler;\n        });\n      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n        google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n          var messages = comm.messages[Symbol.asyncIterator]();\n          function processIteratorResult(result) {\n            var message = result.value;\n            console.log(message)\n            var content = {data: message.data, comm_id};\n            var buffers = []\n            for (var buffer of message.buffers || []) {\n              buffers.push(new DataView(buffer))\n            }\n            var metadata = message.metadata || {};\n            var msg = {content, buffers, metadata}\n            msg_handler(msg);\n            return messages.next().then(processIteratorResult);\n          }\n          return messages.next().then(processIteratorResult);\n        })\n      }\n    }\n\n    JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n      if (comm_id in window.PyViz.comms) {\n        return window.PyViz.comms[comm_id];\n      } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n        var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n        if (msg_handler) {\n          comm.on_msg(msg_handler);\n        }\n      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n        var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n        comm.open();\n        if (msg_handler) {\n          comm.onMsg = msg_handler;\n        }\n      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n        var comm_promise = google.colab.kernel.comms.open(comm_id)\n        comm_promise.then((comm) => {\n          window.PyViz.comms[comm_id] = comm;\n          if (msg_handler) {\n            var messages = comm.messages[Symbol.asyncIterator]();\n            function processIteratorResult(result) {\n              var message = result.value;\n              var content = {data: message.data};\n              var metadata = message.metadata || {comm_id};\n              var msg = {content, metadata}\n              msg_handler(msg);\n              return messages.next().then(processIteratorResult);\n            }\n            return messages.next().then(processIteratorResult);\n          }\n        }) \n        var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n          return comm_promise.then((comm) => {\n            comm.send(data, metadata, buffers, disposeOnDone);\n          });\n        };\n        var comm = {\n          send: sendClosure\n        };\n      }\n      window.PyViz.comms[comm_id] = comm;\n      return comm;\n    }\n    window.PyViz.comm_manager = new JupyterCommManager();\n    \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n  var div = document.createElement(\"div\");\n  var script = document.createElement(\"script\");\n  node.appendChild(div);\n  node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n  var output_area = handle.output_area;\n  var output = handle.output;\n  if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n    return\n  }\n  var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n  var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n  if (id !== undefined) {\n    var nchildren = toinsert.length;\n    var html_node = toinsert[nchildren-1].children[0];\n    html_node.innerHTML = output.data[HTML_MIME_TYPE];\n    var scripts = [];\n    var nodelist = html_node.querySelectorAll(\"script\");\n    for (var i in nodelist) {\n      if (nodelist.hasOwnProperty(i)) {\n        scripts.push(nodelist[i])\n      }\n    }\n\n    scripts.forEach( function (oldScript) {\n      var newScript = document.createElement(\"script\");\n      var attrs = [];\n      var nodemap = oldScript.attributes;\n      for (var j in nodemap) {\n        if (nodemap.hasOwnProperty(j)) {\n          attrs.push(nodemap[j])\n        }\n      }\n      attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n      newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n      oldScript.parentNode.replaceChild(newScript, oldScript);\n    });\n    if (JS_MIME_TYPE in output.data) {\n      toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n    }\n    output_area._hv_plot_id = id;\n    if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n      window.PyViz.plot_index[id] = Bokeh.index[id];\n    } else {\n      window.PyViz.plot_index[id] = null;\n    }\n  } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n    var bk_div = document.createElement(\"div\");\n    bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n    var script_attrs = bk_div.children[0].attributes;\n    for (var i = 0; i < script_attrs.length; i++) {\n      toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n    }\n    // store reference to server id on output_area\n    output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n  }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n  var id = handle.cell.output_area._hv_plot_id;\n  var server_id = handle.cell.output_area._bokeh_server_id;\n  if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n  var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n  if (server_id !== null) {\n    comm.send({event_type: 'server_delete', 'id': server_id});\n    return;\n  } else if (comm !== null) {\n    comm.send({event_type: 'delete', 'id': id});\n  }\n  delete PyViz.plot_index[id];\n  if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n    var doc = window.Bokeh.index[id].model.document\n    doc.clear();\n    const i = window.Bokeh.documents.indexOf(doc);\n    if (i > -1) {\n      window.Bokeh.documents.splice(i, 1);\n    }\n  }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n  delete PyViz.comms[\"hv-extension-comm\"];\n  window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n  handle_clear_output(event, {cell: {output_area: handle.output_area}})\n  handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n  function append_mime(data, metadata, element) {\n    // create a DOM node to render to\n    var toinsert = this.create_output_subarea(\n    metadata,\n    CLASS_NAME,\n    EXEC_MIME_TYPE\n    );\n    this.keyboard_manager.register_events(toinsert);\n    // Render to node\n    var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n    render(props, toinsert[0]);\n    element.append(toinsert);\n    return toinsert\n  }\n\n  events.on('output_added.OutputArea', handle_add_output);\n  events.on('output_updated.OutputArea', handle_update_output);\n  events.on('clear_output.CodeCell', handle_clear_output);\n  events.on('delete.Cell', handle_clear_output);\n  events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n  OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n    safe: true,\n    index: 0\n  });\n}\n\nif (window.Jupyter !== undefined) {\n  try {\n    var events = require('base/js/events');\n    var OutputArea = require('notebook/js/outputarea').OutputArea;\n    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n      register_renderer(events, OutputArea);\n    }\n  } catch(err) {\n  }\n}\n",
      "application/vnd.holoviews_load.v0+json": ""
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<script type=\"esms-options\">{\"shimMode\": true}</script><style>*[data-root-id],\n",
       "*[data-root-id] > * {\n",
       "  box-sizing: border-box;\n",
       "  font-family: var(--jp-ui-font-family);\n",
       "  font-size: var(--jp-ui-font-size1);\n",
       "  color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
       "}\n",
       "\n",
       "/* Override VSCode background color */\n",
       ".cell-output-ipywidget-background:has(\n",
       "    > .cell-output-ipywidget-background > .lm-Widget > *[data-root-id]\n",
       "  ),\n",
       ".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
       "  background-color: transparent !important;\n",
       "}\n",
       "</style>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": "(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  const force = false;\n  const py_version = '3.6.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n  const reloading = true;\n  const Bokeh = root.Bokeh;\n\n  // Set a timeout for this load but only if we are not already initializing\n  if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) {\n        if (callback != null)\n          callback();\n      });\n    } finally {\n      delete root._bokeh_onload_callbacks;\n    }\n    console.debug(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n    if (css_urls == null) css_urls = [];\n    if (js_urls == null) js_urls = [];\n    if (js_modules == null) js_modules = [];\n    if (js_exports == null) js_exports = {};\n\n    root._bokeh_onload_callbacks.push(callback);\n\n    if (root._bokeh_is_loading > 0) {\n      // Don't load bokeh if it is still initializing\n      console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n      // There is nothing to load\n      run_callbacks();\n      return null;\n    }\n\n    function on_load() {\n      root._bokeh_is_loading--;\n      if (root._bokeh_is_loading === 0) {\n        console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n        run_callbacks()\n      }\n    }\n    window._bokeh_on_load = on_load\n\n    function on_error(e) {\n      const src_el = e.srcElement\n      console.error(\"failed to load \" + (src_el.href || src_el.src));\n    }\n\n    const skip = [];\n    if (window.requirejs) {\n      window.requirejs.config({'packages': {}, 'paths': {'h3': 'https://cdn.jsdelivr.net/npm/h3-js@4.1.0/dist/h3-js.umd', 'deck-gl': 'https://cdn.jsdelivr.net/npm/deck.gl@9.0.20/dist.min', 'deck-json': 'https://cdn.jsdelivr.net/npm/@deck.gl/json@9.0.20/dist.min', 'loader-csv': 'https://cdn.jsdelivr.net/npm/@loaders.gl/csv@4.2.2/dist/dist.min', 'loader-json': 'https://cdn.jsdelivr.net/npm/@loaders.gl/json@4.2.2/dist/dist.min', 'loader-tiles': 'https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@4.2.2/dist/dist.min', 'mapbox-gl': 'https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl', 'carto': 'https://cdn.jsdelivr.net/npm/@deck.gl/carto@^9.0.20/dist.min'}, 'shim': {'deck-json': {'deps': ['deck-gl']}, 'deck-gl': {'deps': ['h3']}}});\n      require([\"h3\"], function(h3) {\n        window.h3 = h3\n        on_load()\n      })\n      require([\"deck-gl\"], function(deck) {\n        window.deck = deck\n        on_load()\n      })\n      require([\"deck-json\"], function() {\n        on_load()\n      })\n      require([\"loader-csv\"], function() {\n        on_load()\n      })\n      require([\"loader-json\"], function() {\n        on_load()\n      })\n      require([\"loader-tiles\"], function() {\n        on_load()\n      })\n      require([\"mapbox-gl\"], function(mapboxgl) {\n        window.mapboxgl = mapboxgl\n        on_load()\n      })\n      require([\"carto\"], function() {\n        on_load()\n      })\n      root._bokeh_is_loading = css_urls.length + 8;\n    } else {\n      root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n    }\n\n    const existing_stylesheets = []\n    const links = document.getElementsByTagName('link')\n    for (let i = 0; i < links.length; i++) {\n      const link = links[i]\n      if (link.href != null) {\n        existing_stylesheets.push(link.href)\n      }\n    }\n    for (let i = 0; i < css_urls.length; i++) {\n      const url = css_urls[i];\n      const escaped = encodeURI(url)\n      if (existing_stylesheets.indexOf(escaped) !== -1) {\n        on_load()\n        continue;\n      }\n      const element = document.createElement(\"link\");\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.rel = \"stylesheet\";\n      element.type = \"text/css\";\n      element.href = url;\n      console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n      document.body.appendChild(element);\n    }    if (((window.deck !== undefined) && (!(window.deck instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js', 'https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(encodeURI(urls[i]))\n      }\n    }    if (((window.mapboxgl !== undefined) && (!(window.mapboxgl instanceof HTMLElement))) || window.requirejs) {\n      var urls = ['https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js'];\n      for (var i = 0; i < urls.length; i++) {\n        skip.push(encodeURI(urls[i]))\n      }\n    }    var existing_scripts = []\n    const scripts = document.getElementsByTagName('script')\n    for (let i = 0; i < scripts.length; i++) {\n      var script = scripts[i]\n      if (script.src != null) {\n        existing_scripts.push(script.src)\n      }\n    }\n    for (let i = 0; i < js_urls.length; i++) {\n      const url = js_urls[i];\n      const escaped = encodeURI(url)\n      if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n        if (!window.requirejs) {\n          on_load();\n        }\n        continue;\n      }\n      const element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.async = false;\n      element.src = url;\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n    for (let i = 0; i < js_modules.length; i++) {\n      const url = js_modules[i];\n      const escaped = encodeURI(url)\n      if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n        if (!window.requirejs) {\n          on_load();\n        }\n        continue;\n      }\n      var element = document.createElement('script');\n      element.onload = on_load;\n      element.onerror = on_error;\n      element.async = false;\n      element.src = url;\n      element.type = \"module\";\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.head.appendChild(element);\n    }\n    for (const name in js_exports) {\n      const url = js_exports[name];\n      const escaped = encodeURI(url)\n      if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n        if (!window.requirejs) {\n          on_load();\n        }\n        continue;\n      }\n      var element = document.createElement('script');\n      element.onerror = on_error;\n      element.async = false;\n      element.type = \"module\";\n      console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      element.textContent = `\n      import ${name} from \"${url}\"\n      window.${name} = ${name}\n      window._bokeh_on_load()\n      `\n      document.head.appendChild(element);\n    }\n    if (!js_urls.length && !js_modules.length) {\n      on_load()\n    }\n  };\n\n  function inject_raw_css(css) {\n    const element = document.createElement(\"style\");\n    element.appendChild(document.createTextNode(css));\n    document.body.appendChild(element);\n  }\n\n  const js_urls = [\"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\"];\n  const js_modules = [];\n  const js_exports = {};\n  const css_urls = [\"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.css?v=1.5.4\", \"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/deckglplot/maplibre-gl@4.4.1/dist/maplibre-gl.css?v=1.5.4\"];\n  const inline_js = [    function(Bokeh) {\n      inject_raw_css(\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\");\n    },    function(Bokeh) {\n      inject_raw_css(\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\");\n    },    function(Bokeh) {\n      inject_raw_css(\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\");\n    },    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\n    function(Bokeh) {\n      (function(root, factory) {\n          factory(root[\"Bokeh\"]);\n      })(this, function(Bokeh) {\n        let define;\n        return (function outer(modules, entry) {\n        if (Bokeh != null) {\n          return Bokeh.register_plugin(modules, entry);\n        } else {\n          throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n        }\n      })\n      ({\n        \"custom/main\": function(require, module, exports) {\n          const models = {\n            \"CustomInspectTool\": require(\"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\").CustomInspectTool\n          };\n          require(\"base\").register_models(models);\n          module.exports = models;\n        },\n        \"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\": function(require, module, exports) {\n      \"use strict\";\n      var _a;\n      Object.defineProperty(exports, \"__esModule\", { value: true });\n      exports.CustomInspectTool = exports.CustomInspectToolView = void 0;\n      const inspect_tool_1 = require(\"models/tools/inspectors/inspect_tool\");\n      class CustomInspectToolView extends inspect_tool_1.InspectToolView {\n          connect_signals() {\n              super.connect_signals();\n              this.on_change([this.model.properties.active], () => {\n                  this.model._active = this.model.active;\n              });\n          }\n      }\n      exports.CustomInspectToolView = CustomInspectToolView;\n      CustomInspectToolView.__name__ = \"CustomInspectToolView\";\n      class CustomInspectTool extends inspect_tool_1.InspectTool {\n          constructor(attrs) {\n              super(attrs);\n          }\n      }\n      exports.CustomInspectTool = CustomInspectTool;\n      _a = CustomInspectTool;\n      CustomInspectTool.__name__ = \"CustomInspectTool\";\n      (() => {\n          _a.prototype.default_view = CustomInspectToolView;\n          _a.define(({ Boolean }) => ({\n              _active: [Boolean, true]\n          }));\n          _a.register_alias(\"customInspect\", () => new _a());\n      })();\n      //# sourceMappingURL=graph_inspect_widget.py:CustomInspectTool.js.map\n      }\n      }, \"custom/main\");\n      ;\n      });\n\n    },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n  ];\n\n  function run_inline_js() {\n    if ((root.Bokeh !== undefined) || (force === true)) {\n      for (let i = 0; i < inline_js.length; i++) {\n        try {\n          inline_js[i].call(root, root.Bokeh);\n        } catch(e) {\n          if (!reloading) {\n            throw e;\n          }\n        }\n      }\n      // Cache old bokeh versions\n      if (Bokeh != undefined && !reloading) {\n        var NewBokeh = root.Bokeh;\n        if (Bokeh.versions === undefined) {\n          Bokeh.versions = new Map();\n        }\n        if (NewBokeh.version !== Bokeh.version) {\n          Bokeh.versions.set(NewBokeh.version, NewBokeh)\n        }\n        root.Bokeh = Bokeh;\n      }\n    } else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    }\n    root._bokeh_is_initializing = false\n  }\n\n  function load_or_wait() {\n    // Implement a backoff loop that tries to ensure we do not load multiple\n    // versions of Bokeh and its dependencies at the same time.\n    // In recent versions we use the root._bokeh_is_initializing flag\n    // to determine whether there is an ongoing attempt to initialize\n    // bokeh, however for backward compatibility we also try to ensure\n    // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n    // before older versions are fully initialized.\n    if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n      // If the timeout and bokeh was not successfully loaded we reset\n      // everything and try loading again\n      root._bokeh_timeout = Date.now() + 5000;\n      root._bokeh_is_initializing = false;\n      root._bokeh_onload_callbacks = undefined;\n      root._bokeh_is_loading = 0\n      console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n      load_or_wait();\n    } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n      setTimeout(load_or_wait, 100);\n    } else {\n      root._bokeh_is_initializing = true\n      root._bokeh_onload_callbacks = []\n      const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n      if (!reloading && !bokeh_loaded) {\n        if (root.Bokeh) {\n          root.Bokeh = undefined;\n        }\n        console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n      }\n      load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n        console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n        run_inline_js();\n      });\n    }\n  }\n  // Give older versions of the autoload script a head-start to ensure\n  // they initialize before we start loading newer version.\n  setTimeout(load_or_wait, 100)\n}(window));",
      "application/vnd.holoviews_load.v0+json": ""
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n  window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n    function JupyterCommManager() {\n    }\n\n    JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n      if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n        comm_manager.register_target(comm_id, function(comm) {\n          comm.on_msg(msg_handler);\n        });\n      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n        window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n          comm.onMsg = msg_handler;\n        });\n      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n        google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n          var messages = comm.messages[Symbol.asyncIterator]();\n          function processIteratorResult(result) {\n            var message = result.value;\n            console.log(message)\n            var content = {data: message.data, comm_id};\n            var buffers = []\n            for (var buffer of message.buffers || []) {\n              buffers.push(new DataView(buffer))\n            }\n            var metadata = message.metadata || {};\n            var msg = {content, buffers, metadata}\n            msg_handler(msg);\n            return messages.next().then(processIteratorResult);\n          }\n          return messages.next().then(processIteratorResult);\n        })\n      }\n    }\n\n    JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n      if (comm_id in window.PyViz.comms) {\n        return window.PyViz.comms[comm_id];\n      } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n        var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n        var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n        if (msg_handler) {\n          comm.on_msg(msg_handler);\n        }\n      } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n        var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n        comm.open();\n        if (msg_handler) {\n          comm.onMsg = msg_handler;\n        }\n      } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n        var comm_promise = google.colab.kernel.comms.open(comm_id)\n        comm_promise.then((comm) => {\n          window.PyViz.comms[comm_id] = comm;\n          if (msg_handler) {\n            var messages = comm.messages[Symbol.asyncIterator]();\n            function processIteratorResult(result) {\n              var message = result.value;\n              var content = {data: message.data};\n              var metadata = message.metadata || {comm_id};\n              var msg = {content, metadata}\n              msg_handler(msg);\n              return messages.next().then(processIteratorResult);\n            }\n            return messages.next().then(processIteratorResult);\n          }\n        }) \n        var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n          return comm_promise.then((comm) => {\n            comm.send(data, metadata, buffers, disposeOnDone);\n          });\n        };\n        var comm = {\n          send: sendClosure\n        };\n      }\n      window.PyViz.comms[comm_id] = comm;\n      return comm;\n    }\n    window.PyViz.comm_manager = new JupyterCommManager();\n    \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n  var div = document.createElement(\"div\");\n  var script = document.createElement(\"script\");\n  node.appendChild(div);\n  node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n  var output_area = handle.output_area;\n  var output = handle.output;\n  if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n    return\n  }\n  var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n  var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n  if (id !== undefined) {\n    var nchildren = toinsert.length;\n    var html_node = toinsert[nchildren-1].children[0];\n    html_node.innerHTML = output.data[HTML_MIME_TYPE];\n    var scripts = [];\n    var nodelist = html_node.querySelectorAll(\"script\");\n    for (var i in nodelist) {\n      if (nodelist.hasOwnProperty(i)) {\n        scripts.push(nodelist[i])\n      }\n    }\n\n    scripts.forEach( function (oldScript) {\n      var newScript = document.createElement(\"script\");\n      var attrs = [];\n      var nodemap = oldScript.attributes;\n      for (var j in nodemap) {\n        if (nodemap.hasOwnProperty(j)) {\n          attrs.push(nodemap[j])\n        }\n      }\n      attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n      newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n      oldScript.parentNode.replaceChild(newScript, oldScript);\n    });\n    if (JS_MIME_TYPE in output.data) {\n      toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n    }\n    output_area._hv_plot_id = id;\n    if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n      window.PyViz.plot_index[id] = Bokeh.index[id];\n    } else {\n      window.PyViz.plot_index[id] = null;\n    }\n  } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n    var bk_div = document.createElement(\"div\");\n    bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n    var script_attrs = bk_div.children[0].attributes;\n    for (var i = 0; i < script_attrs.length; i++) {\n      toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n    }\n    // store reference to server id on output_area\n    output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n  }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n  var id = handle.cell.output_area._hv_plot_id;\n  var server_id = handle.cell.output_area._bokeh_server_id;\n  if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n  var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n  if (server_id !== null) {\n    comm.send({event_type: 'server_delete', 'id': server_id});\n    return;\n  } else if (comm !== null) {\n    comm.send({event_type: 'delete', 'id': id});\n  }\n  delete PyViz.plot_index[id];\n  if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n    var doc = window.Bokeh.index[id].model.document\n    doc.clear();\n    const i = window.Bokeh.documents.indexOf(doc);\n    if (i > -1) {\n      window.Bokeh.documents.splice(i, 1);\n    }\n  }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n  delete PyViz.comms[\"hv-extension-comm\"];\n  window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n  handle_clear_output(event, {cell: {output_area: handle.output_area}})\n  handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n  function append_mime(data, metadata, element) {\n    // create a DOM node to render to\n    var toinsert = this.create_output_subarea(\n    metadata,\n    CLASS_NAME,\n    EXEC_MIME_TYPE\n    );\n    this.keyboard_manager.register_events(toinsert);\n    // Render to node\n    var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n    render(props, toinsert[0]);\n    element.append(toinsert);\n    return toinsert\n  }\n\n  events.on('output_added.OutputArea', handle_add_output);\n  events.on('output_updated.OutputArea', handle_update_output);\n  events.on('clear_output.CodeCell', handle_clear_output);\n  events.on('delete.Cell', handle_clear_output);\n  events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n  OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n    safe: true,\n    index: 0\n  });\n}\n\nif (window.Jupyter !== undefined) {\n  try {\n    var events = require('base/js/events');\n    var OutputArea = require('notebook/js/outputarea').OutputArea;\n    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n      register_renderer(events, OutputArea);\n    }\n  } catch(err) {\n  }\n}\n",
      "application/vnd.holoviews_load.v0+json": ""
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.holoviews_exec.v0+json": "",
      "text/html": [
       "<div id='3c27968b-3c60-4718-a309-e03e7467f97d'>\n",
       "  <div id=\"d4fe1e3d-0395-46c0-97d1-938be19e5f00\" data-root-id=\"3c27968b-3c60-4718-a309-e03e7467f97d\" style=\"display: contents;\"></div>\n",
       "</div>\n",
       "<script type=\"application/javascript\">(function(root) {\n",
       "  var docs_json = {\"2fbc0981-a679-4d91-a574-dae8e0272997\":{\"version\":\"3.6.2\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"panel.models.browser.BrowserInfo\",\"id\":\"3c27968b-3c60-4718-a309-e03e7467f97d\"},{\"type\":\"object\",\"name\":\"panel.models.comm_manager.CommManager\",\"id\":\"dcb2d684-5f9f-472c-93e2-bfea9e363c6f\",\"attributes\":{\"plot_id\":\"3c27968b-3c60-4718-a309-e03e7467f97d\",\"comm_id\":\"b10e5eb4819c4462bc8714a0e1b4e7d4\",\"client_comm_id\":\"08f5dee7ef784ad88599c1151eb7a0b3\"}}],\"defs\":[{\"type\":\"model\",\"name\":\"ReactiveHTML1\"},{\"type\":\"model\",\"name\":\"FlexBox1\",\"properties\":[{\"name\":\"align_content\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"align_items\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"flex_direction\",\"kind\":\"Any\",\"default\":\"row\"},{\"name\":\"flex_wrap\",\"kind\":\"Any\",\"default\":\"wrap\"},{\"name\":\"gap\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"justify_content\",\"kind\":\"Any\",\"default\":\"flex-start\"}]},{\"type\":\"model\",\"name\":\"FloatPanel1\",\"properties\":[{\"name\":\"config\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"contained\",\"kind\":\"Any\",\"default\":true},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"right-top\"},{\"name\":\"offsetx\",\"kind\":\"Any\",\"default\":null},{\"name\":\"offsety\",\"kind\":\"Any\",\"default\":null},{\"name\":\"theme\",\"kind\":\"Any\",\"default\":\"primary\"},{\"name\":\"status\",\"kind\":\"Any\",\"default\":\"normalized\"}]},{\"type\":\"model\",\"name\":\"GridStack1\",\"properties\":[{\"name\":\"mode\",\"kind\":\"Any\",\"default\":\"warn\"},{\"name\":\"ncols\",\"kind\":\"Any\",\"default\":null},{\"name\":\"nrows\",\"kind\":\"Any\",\"default\":null},{\"name\":\"allow_resize\",\"kind\":\"Any\",\"default\":true},{\"name\":\"allow_drag\",\"kind\":\"Any\",\"default\":true},{\"name\":\"state\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"drag1\",\"properties\":[{\"name\":\"slider_width\",\"kind\":\"Any\",\"default\":5},{\"name\":\"slider_color\",\"kind\":\"Any\",\"default\":\"black\"},{\"name\":\"value\",\"kind\":\"Any\",\"default\":50}]},{\"type\":\"model\",\"name\":\"click1\",\"properties\":[{\"name\":\"terminal_output\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"debug_name\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"clears\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"FastWrapper1\",\"properties\":[{\"name\":\"object\",\"kind\":\"Any\",\"default\":null},{\"name\":\"style\",\"kind\":\"Any\",\"default\":null}]},{\"type\":\"model\",\"name\":\"NotificationAreaBase1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"NotificationArea1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"notifications\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0},{\"name\":\"types\",\"kind\":\"Any\",\"default\":[{\"type\":\"map\",\"entries\":[[\"type\",\"warning\"],[\"background\",\"#ffc107\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-exclamation-triangle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]},{\"type\":\"map\",\"entries\":[[\"type\",\"info\"],[\"background\",\"#007bff\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-info-circle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]}]}]},{\"type\":\"model\",\"name\":\"Notification\",\"properties\":[{\"name\":\"background\",\"kind\":\"Any\",\"default\":null},{\"name\":\"duration\",\"kind\":\"Any\",\"default\":3000},{\"name\":\"icon\",\"kind\":\"Any\",\"default\":null},{\"name\":\"message\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"notification_type\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_destroyed\",\"kind\":\"Any\",\"default\":false}]},{\"type\":\"model\",\"name\":\"TemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"BootstrapTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"TemplateEditor1\",\"properties\":[{\"name\":\"layout\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"MaterialTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"ReactiveESM1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"JSComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"ReactComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"AnyWidgetComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"request_value1\",\"properties\":[{\"name\":\"fill\",\"kind\":\"Any\",\"default\":\"none\"},{\"name\":\"_synced\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_request_sync\",\"kind\":\"Any\",\"default\":0}]}]}};\n",
       "  var render_items = [{\"docid\":\"2fbc0981-a679-4d91-a574-dae8e0272997\",\"roots\":{\"3c27968b-3c60-4718-a309-e03e7467f97d\":\"d4fe1e3d-0395-46c0-97d1-938be19e5f00\"},\"root_ids\":[\"3c27968b-3c60-4718-a309-e03e7467f97d\"]}];\n",
       "  var docs = Object.values(docs_json)\n",
       "  if (!docs) {\n",
       "    return\n",
       "  }\n",
       "  const py_version = docs[0].version.replace('rc', '-rc.').replace('.dev', '-dev.')\n",
       "  async function embed_document(root) {\n",
       "    var Bokeh = get_bokeh(root)\n",
       "    await Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
       "    for (const render_item of render_items) {\n",
       "      for (const root_id of render_item.root_ids) {\n",
       "\tconst id_el = document.getElementById(root_id)\n",
       "\tif (id_el.children.length && id_el.children[0].hasAttribute('data-root-id')) {\n",
       "\t  const root_el = id_el.children[0]\n",
       "\t  root_el.id = root_el.id + '-rendered'\n",
       "\t  for (const child of root_el.children) {\n",
       "            // Ensure JupyterLab does not capture keyboard shortcuts\n",
       "            // see: https://jupyterlab.readthedocs.io/en/4.1.x/extension/notebook.html#keyboard-interaction-model\n",
       "\t    child.setAttribute('data-lm-suppress-shortcuts', 'true')\n",
       "\t  }\n",
       "\t}\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "  function get_bokeh(root) {\n",
       "    if (root.Bokeh === undefined) {\n",
       "      return null\n",
       "    } else if (root.Bokeh.version !== py_version) {\n",
       "      if (root.Bokeh.versions === undefined || !root.Bokeh.versions.has(py_version)) {\n",
       "\treturn null\n",
       "      }\n",
       "      return root.Bokeh.versions.get(py_version);\n",
       "    } else if (root.Bokeh.version === py_version) {\n",
       "      return root.Bokeh\n",
       "    }\n",
       "    return null\n",
       "  }\n",
       "  function is_loaded(root) {\n",
       "    var Bokeh = get_bokeh(root)\n",
       "    return (Bokeh != null && Bokeh.Panel !== undefined && ( root.deck !== undefined) && ( root.deck !== undefined))\n",
       "  }\n",
       "  if (is_loaded(root)) {\n",
       "    embed_document(root);\n",
       "  } else {\n",
       "    var attempts = 0;\n",
       "    var timer = setInterval(function(root) {\n",
       "      if (is_loaded(root)) {\n",
       "        clearInterval(timer);\n",
       "        embed_document(root);\n",
       "      } else if (document.readyState == \"complete\") {\n",
       "        attempts++;\n",
       "        if (attempts > 200) {\n",
       "          clearInterval(timer);\n",
       "\t  var Bokeh = get_bokeh(root)\n",
       "\t  if (Bokeh == null || Bokeh.Panel == null) {\n",
       "            console.warn(\"Panel: ERROR: Unable to run Panel code because Bokeh or Panel library is missing\");\n",
       "\t  } else {\n",
       "\t    console.warn(\"Panel: WARNING: Attempting to render but not all required libraries could be resolved.\")\n",
       "\t    embed_document(root)\n",
       "\t  }\n",
       "        }\n",
       "      }\n",
       "    }, 25, root)\n",
       "  }\n",
       "})(window);</script>"
      ]
     },
     "metadata": {
      "application/vnd.holoviews_exec.v0+json": {
       "id": "3c27968b-3c60-4718-a309-e03e7467f97d"
      }
     },
     "output_type": "display_data"
    },
    {
     "data": {},
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {},
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.holoviews_exec.v0+json": "",
      "text/html": [
       "<div id='d8fb88cc-1bae-4a54-a455-83ab4e59be12'>\n",
       "  <div id=\"ae386224-877d-4305-82dd-7dc4bfb77cfa\" data-root-id=\"d8fb88cc-1bae-4a54-a455-83ab4e59be12\" style=\"display: contents;\"></div>\n",
       "</div>\n",
       "<script type=\"application/javascript\">(function(root) {\n",
       "  var docs_json = {\"ac83bbab-1fc2-45fd-bf74-8a83d9396f29\":{\"version\":\"3.6.2\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"GridBox\",\"id\":\"d8fb88cc-1bae-4a54-a455-83ab4e59be12\",\"attributes\":{\"rows\":null,\"cols\":null,\"name\":\"GridSpec00465\",\"stylesheets\":[\"\\n:host(.pn-loading):before, .pn-loading:before {\\n  background-color: #c3c3c3;\\n  mask-size: auto calc(min(50%, 400px));\\n  -webkit-mask-size: auto calc(min(50%, 400px));\\n}\",{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"af8ec279-6516-412a-85c1-e630e8a73670\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.5.4/dist/css/loading.css\"}},\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\",\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\",\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\",{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"9b43bae7-e490-4819-a4a5-e1a1f83d1536\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.5.4/dist/css/gridspec.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"447be690-c979-4a42-8994-7f29f7ae3469\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/theme/default.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"5a8b8bf1-32dd-4d1d-8a8c-d9fa2004434e\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.5.4/dist/bundled/theme/native.css\"}}],\"min_width\":1200,\"margin\":0,\"sizing_mode\":\"scale_width\",\"align\":\"start\",\"children\":[[{\"type\":\"object\",\"name\":\"GridBox\",\"id\":\"8c0666f5-fdc0-43a0-aee7-7f3ff2b8ae98\",\"attributes\":{\"rows\":null,\"cols\":null,\"name\":\"GridSpec00310\",\"stylesheets\":[\"\\n:host(.pn-loading):before, .pn-loading:before {\\n  background-color: #c3c3c3;\\n  mask-size: auto calc(min(50%, 400px));\\n  -webkit-mask-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"af8ec279-6516-412a-85c1-e630e8a73670\"},\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\",\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\",\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\",{\"id\":\"9b43bae7-e490-4819-a4a5-e1a1f83d1536\"},{\"id\":\"447be690-c979-4a42-8994-7f29f7ae3469\"},{\"id\":\"5a8b8bf1-32dd-4d1d-8a8c-d9fa2004434e\"}],\"width\":1200,\"height\":800,\"margin\":0,\"sizing_mode\":\"fixed\",\"align\":\"start\",\"children\":[[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"081f07d9-981d-420e-b28d-ea3356999c22\",\"attributes\":{\"subscribed_events\":{\"type\":\"set\",\"entries\":[\"reset\",\"selectiongeometry\"]},\"width\":400,\"height\":320,\"margin\":[5,10],\"sizing_mode\":\"stretch_both\",\"align\":\"start\",\"x_range\":{\"type\":\"object\",\"name\":\"FactorRange\",\"id\":\"1e6cd0d5-f22e-4984-83c5-9e1991fbe59b\",\"attributes\":{\"name\":\"sex\",\"tags\":[[[\"sex\",null]],[]],\"factors\":[\"f\",\"m\"]}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"e559495e-703a-4816-8f15-98027a724271\",\"attributes\":{\"name\":\"y\",\"tags\":[[[\"y\",null]],{\"type\":\"map\",\"entries\":[[\"invert_yaxis\",false],[\"autorange\",false]]}],\"end\":29646946.2,\"reset_start\":0.0,\"reset_end\":29646946.2}},\"x_scale\":{\"type\":\"object\",\"name\":\"CategoricalScale\",\"id\":\"afda8be5-f3c6-450e-9788-c3b9a13464d8\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"89ad8858-e97a-49d3-b376-d88eb3ea605a\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"be38118f-2720-4d91-9110-b26f67490385\",\"attributes\":{\"text\":\"sex\",\"text_color\":\"black\",\"text_font_size\":\"12pt\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"51b2d0e2-17be-489c-892c-65866573aaae\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"1780efb3-f0f4-476e-b551-5d2cb2334226\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"ed4032c2-4e59-46cd-9178-9299c897d36e\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"36923509-2dcc-4deb-9f71-630fd1443e4a\"},\"data\":{\"type\":\"map\",\"entries\":[[\"sex\",[\"f\",\"m\"]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"aVfDAa39uAE=\"},\"shape\":[2],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"41e917b5-82ad-46c2-be34-b914caa55814\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"af863e1f-3457-40da-926d-cbd924e2dc5d\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"0f7f640c-cf7c-4cea-bb11-c16f5856cf0c\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"sex\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"selection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"8d05ab4b-4b77-441c-b512-8b36a1937017\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"sex\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"black\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"line_width\":{\"type\":\"value\",\"value\":1},\"line_join\":{\"type\":\"value\",\"value\":\"bevel\"},\"line_cap\":{\"type\":\"value\",\"value\":\"butt\"},\"line_dash\":{\"type\":\"value\",\"value\":[]},\"line_dash_offset\":{\"type\":\"value\",\"value\":0},\"fill_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_scale\":{\"type\":\"value\",\"value\":12.0},\"hatch_pattern\":{\"type\":\"value\",\"value\":null},\"hatch_weight\":{\"type\":\"value\",\"value\":1.0}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"62d78fa9-940a-48be-a5f4-4b4e2fe4858e\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"sex\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"52dbae3c-3901-4430-9e51-a2fd5290d8b9\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"sex\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"cd0bed67-2415-4604-b190-59834cffa84a\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"75cc8786-f239-4c77-b42d-02b2d8361fa4\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"4ab721a9-cad6-45c8-b2a6-050dbe6036e3\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"d99ce2ad-7229-4d44-a006-d83de847c171\"},\"data\":{\"type\":\"map\",\"entries\":[[\"sex\",[\"f\",\"m\"]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"aVfDAa39uAE=\"},\"shape\":[2],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"1b15fcf4-dda3-4b2b-8827-e579e59d14b5\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"51d4b99f-a1c8-4763-8dac-265a114eb499\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"ebde3c2f-42a2-49e7-bca2-642910128354\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"sex\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#4292c6\"},\"hatch_color\":{\"type\":\"value\",\"value\":\"#fc4f30\"}}},\"selection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"364df810-656b-4101-95f6-b492565a1910\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"sex\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"black\"},\"line_alpha\":{\"type\":\"value\",\"value\":1.0},\"line_width\":{\"type\":\"value\",\"value\":1},\"line_join\":{\"type\":\"value\",\"value\":\"bevel\"},\"line_cap\":{\"type\":\"value\",\"value\":\"butt\"},\"line_dash\":{\"type\":\"value\",\"value\":[]},\"line_dash_offset\":{\"type\":\"value\",\"value\":0},\"fill_color\":{\"type\":\"value\",\"value\":\"#4292c6\"},\"fill_alpha\":{\"type\":\"value\",\"value\":1.0},\"hatch_color\":{\"type\":\"value\",\"value\":\"#fc4f30\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":1.0},\"hatch_scale\":{\"type\":\"value\",\"value\":12.0},\"hatch_pattern\":{\"type\":\"value\",\"value\":null},\"hatch_weight\":{\"type\":\"value\",\"value\":1.0}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"4dfde54a-8d8a-45bb-a19a-b270c29b95a1\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"sex\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#4292c6\"},\"hatch_color\":{\"type\":\"value\",\"value\":\"#fc4f30\"}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"50e094f4-aecb-4e5b-a116-ef228cab7b08\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"sex\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#4292c6\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"value\",\"value\":\"#fc4f30\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"c574b70e-6f43-4df5-86c5-a60cf5e9e0e6\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"c1c9fb7d-7628-49b3-86c6-97e0da1b414f\",\"attributes\":{\"tags\":[\"hv_created\"],\"renderers\":\"auto\",\"zoom_together\":\"none\"}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"8a4e2602-d2a8-4aca-85e9-5016626d32cb\"},{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"0ff26e92-f5b2-4f35-8b03-873cb2e42fde\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"9119dfba-f719-4ded-ac41-bfcfde0f6dc2\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"4c8d2444-ff70-4dac-ba2e-5b504b966e09\",\"attributes\":{\"syncable\":false,\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"handles\":{\"type\":\"object\",\"name\":\"BoxInteractionHandles\",\"id\":\"3a2fcbbf-146b-4dab-8c1c-f1a4520a35c7\",\"attributes\":{\"all\":{\"type\":\"object\",\"name\":\"AreaVisuals\",\"id\":\"cf48c9f5-85e4-4a84-b6d6-6589ea4a026a\",\"attributes\":{\"fill_color\":\"white\",\"hover_fill_color\":\"lightgray\"}}}}}}}},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"fe44b0f3-a0ec-4e28-a605-fe0f22f8c848\"},{\"type\":\"object\",\"name\":\"BoxSelectTool\",\"id\":\"44b8a234-a362-4583-9074-9207953dab58\",\"attributes\":{\"renderers\":\"auto\",\"dimensions\":\"width\",\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"f3f69068-5686-4e66-924d-76825479d6e3\",\"attributes\":{\"syncable\":false,\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"editable\":true,\"handles\":{\"type\":\"object\",\"name\":\"BoxInteractionHandles\",\"id\":\"93b95686-6fc0-4e5f-87a8-273fc22e413a\",\"attributes\":{\"all\":{\"type\":\"object\",\"name\":\"AreaVisuals\",\"id\":\"170e4fa7-20cd-4e68-a610-f4f10e4fc6fd\",\"attributes\":{\"fill_color\":\"white\",\"hover_fill_color\":\"lightgray\"}}}}}}}}],\"active_drag\":{\"id\":\"44b8a234-a362-4583-9074-9207953dab58\"}}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"549fac6f-9670-4860-8740-de8fbcb09a3a\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"7399e11f-4a46-443f-8347-384ef1f072a3\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"0a3c50ad-f106-4ac7-9b40-911947903b0d\"},\"axis_label\":\"frequency\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"e1b270be-bac4-4d9e-a28a-c57fd67c0080\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"CategoricalAxis\",\"id\":\"9b2e378a-acbd-433a-9e83-d02590dacc51\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"CategoricalTicker\",\"id\":\"8ba70a9e-1fe0-4762-83a6-83a6f5228412\"},\"formatter\":{\"type\":\"object\",\"name\":\"CategoricalTickFormatter\",\"id\":\"4884ad6b-b70e-47c7-a6fa-36a17c99f551\"},\"axis_label\":\"sex\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"2adbf493-bbfa-458a-b90d-ab3e8a804791\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"6625b236-a919-4876-ba19-2c9289b6ab8a\",\"attributes\":{\"axis\":{\"id\":\"9b2e378a-acbd-433a-9e83-d02590dacc51\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"82fdc1ba-3c51-4030-8389-47e45e85bc5e\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"549fac6f-9670-4860-8740-de8fbcb09a3a\"},\"grid_line_color\":null}}],\"min_border_top\":10,\"min_border_bottom\":10,\"min_border_left\":10,\"min_border_right\":10,\"output_backend\":\"webgl\",\"hold_render\":false}},0,0,2,4],[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"e24c99d1-b3c0-46e4-a40e-3d2c3814dbbf\",\"attributes\":{\"subscribed_events\":{\"type\":\"set\",\"entries\":[\"reset\",\"rangesupdate\",\"selectiongeometry\"]},\"width\":800,\"height\":800,\"margin\":[5,10],\"sizing_mode\":\"stretch_both\",\"align\":\"start\",\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"6c77bc11-f920-4e25-9577-4e98d3791400\",\"attributes\":{\"name\":\"long\",\"tags\":[[[\"long\",null]],[]],\"start\":-6.368373870849609,\"end\":2.7000911235809326,\"reset_start\":-6.368373870849609,\"reset_end\":2.7000911235809326}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"63c6853c-33cd-4a06-8291-25f6f8a3344a\",\"attributes\":{\"name\":\"lat\",\"tags\":[[[\"lat\",null]],{\"type\":\"map\",\"entries\":[[\"invert_yaxis\",false],[\"autorange\",false]]}],\"start\":49.519039154052734,\"end\":56.261409759521484,\"reset_start\":49.519039154052734,\"reset_end\":56.261409759521484}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"a32c38ce-8368-4986-b262-5be953a7ab5c\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"8706a51a-a103-4773-882f-da0f5d193ade\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"67ac7f19-61fe-48ad-becd-4427ca41deb8\",\"attributes\":{\"text\":\"Scatter plot for lat count\",\"text_color\":\"black\",\"text_font_size\":\"12pt\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"79bca7d5-cf07-4ca5-a83b-5bd931594639\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"4aa766b8-066b-4cc4-9720-3be4e6f2531f\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"e123949b-8c89-46ea-bc51-50c9297bfe41\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"81be3139-cd19-42d6-a07f-da9a3707d075\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[-6.368373870849609]],[\"y\",[49.519039154052734]],[\"dw\",[9.068464994430542]],[\"dh\",[6.74237060546875]],[\"image\",[{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"[encoded data, 1706668 characters]\"},\"shape\":[400,400],\"dtype\":\"float64\",\"order\":\"little\"}]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"c7c274d3-af6f-4035-8222-6d94af7b34b2\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"d9a92b0f-8687-43b1-ab01-67b108caa59c\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Image\",\"id\":\"3c5ae64d-7a8f-4bf4-8258-a39593ebebe3\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"dw\":{\"type\":\"field\",\"field\":\"dw\"},\"dh\":{\"type\":\"field\",\"field\":\"dh\"},\"image\":{\"type\":\"field\",\"field\":\"image\"},\"color_mapper\":{\"type\":\"object\",\"name\":\"EqHistColorMapper\",\"id\":\"4f7a5df2-eded-4efd-9239-a00a1cda963a\",\"attributes\":{\"palette\":[\"#08306b\",\"#08519c\",\"#2171b5\",\"#4292c6\",\"#6baed6\",\"#9ecae1\",\"#c6dbef\",\"#deebf7\",\"#f7fbff\"],\"nan_color\":\"rgba(0, 0, 0, 0)\",\"low\":1.0,\"high\":66226.0,\"rescale_discrete_levels\":true}}}},\"selection_glyph\":{\"type\":\"object\",\"name\":\"Image\",\"id\":\"8174043a-8a0a-4620-9d67-f48c791d13b6\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"dw\":{\"type\":\"field\",\"field\":\"dw\"},\"dh\":{\"type\":\"field\",\"field\":\"dh\"},\"global_alpha\":{\"type\":\"value\",\"value\":1},\"image\":{\"type\":\"field\",\"field\":\"image\"},\"color_mapper\":{\"id\":\"4f7a5df2-eded-4efd-9239-a00a1cda963a\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Image\",\"id\":\"4d145ff5-c2c5-4c21-86c1-b0cf257bdf1f\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"dw\":{\"type\":\"field\",\"field\":\"dw\"},\"dh\":{\"type\":\"field\",\"field\":\"dh\"},\"global_alpha\":{\"type\":\"value\",\"value\":1},\"image\":{\"type\":\"field\",\"field\":\"image\"},\"color_mapper\":{\"id\":\"4f7a5df2-eded-4efd-9239-a00a1cda963a\"}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Image\",\"id\":\"2b0cf25f-a410-46ae-ba22-21639eb907ab\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"dw\":{\"type\":\"field\",\"field\":\"dw\"},\"dh\":{\"type\":\"field\",\"field\":\"dh\"},\"global_alpha\":{\"type\":\"value\",\"value\":1},\"image\":{\"type\":\"field\",\"field\":\"image\"},\"color_mapper\":{\"id\":\"4f7a5df2-eded-4efd-9239-a00a1cda963a\"}}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"b0fa5baa-0545-4a68-b58a-a3bfdf83c555\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"b8760384-457f-49eb-bb4a-d2c36a4fdef4\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"7ac1b04d-7b14-4d17-87b8-2bc3900161c2\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"df39e8ba-88b0-420d-839b-74e8a51af7df\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[-6.368373870849609]],[\"y\",[49.519039154052734]],[\"dw\",[9.068464994430542]],[\"dh\",[6.74237060546875]],[\"image\",[{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"[encoded data, 1706668 characters]\"},\"shape\":[400,400],\"dtype\":\"float64\",\"order\":\"little\"}]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"aef88c63-3f54-43a2-965c-18f45b27e209\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"4ad36b34-4b4f-4af2-b5d4-7be1d09b8f75\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Image\",\"id\":\"5080ab65-5bbb-4d39-9552-3ee3b144d60d\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"dw\":{\"type\":\"field\",\"field\":\"dw\"},\"dh\":{\"type\":\"field\",\"field\":\"dh\"},\"global_alpha\":{\"type\":\"value\",\"value\":0.2},\"image\":{\"type\":\"field\",\"field\":\"image\"},\"color_mapper\":{\"type\":\"object\",\"name\":\"EqHistColorMapper\",\"id\":\"ad2e1aa0-18b3-4d4a-8d5b-af493ae1b7d1\",\"attributes\":{\"palette\":[\"#08306b\",\"#08519c\",\"#2171b5\",\"#4292c6\",\"#6baed6\",\"#9ecae1\",\"#c6dbef\",\"#deebf7\",\"#f7fbff\"],\"nan_color\":\"rgba(0, 0, 0, 0)\",\"low\":1.0,\"high\":66226.0,\"rescale_discrete_levels\":true}}}},\"selection_glyph\":{\"type\":\"object\",\"name\":\"Image\",\"id\":\"11f676d9-5ac2-49d5-b1b6-743cdc1bbcac\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"dw\":{\"type\":\"field\",\"field\":\"dw\"},\"dh\":{\"type\":\"field\",\"field\":\"dh\"},\"global_alpha\":{\"type\":\"value\",\"value\":0.2},\"image\":{\"type\":\"field\",\"field\":\"image\"},\"color_mapper\":{\"id\":\"ad2e1aa0-18b3-4d4a-8d5b-af493ae1b7d1\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Image\",\"id\":\"54432918-d171-4eb1-a4d6-979aaea8da68\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"dw\":{\"type\":\"field\",\"field\":\"dw\"},\"dh\":{\"type\":\"field\",\"field\":\"dh\"},\"global_alpha\":{\"type\":\"value\",\"value\":0.2},\"image\":{\"type\":\"field\",\"field\":\"image\"},\"color_mapper\":{\"id\":\"ad2e1aa0-18b3-4d4a-8d5b-af493ae1b7d1\"}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Image\",\"id\":\"b128b6df-18cc-450d-a5eb-2d075fee4a29\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"dw\":{\"type\":\"field\",\"field\":\"dw\"},\"dh\":{\"type\":\"field\",\"field\":\"dh\"},\"global_alpha\":{\"type\":\"value\",\"value\":0.2},\"image\":{\"type\":\"field\",\"field\":\"image\"},\"color_mapper\":{\"id\":\"ad2e1aa0-18b3-4d4a-8d5b-af493ae1b7d1\"}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"724bfb03-0aca-4296-9b5e-0bc2313ed2c6\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"a75e3fce-ac98-4a01-b67b-315061bf428b\",\"attributes\":{\"tags\":[\"hv_created\"],\"renderers\":\"auto\",\"zoom_together\":\"none\"}},{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"ab4bf321-02a2-4cd5-94a5-690e9e8dae32\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"961439d6-ef36-4928-a212-a415d346b5c9\"},{\"type\":\"object\",\"name\":\"BoxSelectTool\",\"id\":\"0513417d-2348-4ccb-ae21-bc3dd2c413dd\",\"attributes\":{\"renderers\":\"auto\",\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"9a66224a-6564-4de0-82b3-7980731e4d13\",\"attributes\":{\"syncable\":false,\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"editable\":true,\"handles\":{\"type\":\"object\",\"name\":\"BoxInteractionHandles\",\"id\":\"f8776461-a7bc-4e39-a79b-c88d07df38ee\",\"attributes\":{\"all\":{\"type\":\"object\",\"name\":\"AreaVisuals\",\"id\":\"d3591bc6-d8a5-4a52-91fd-33340feda052\",\"attributes\":{\"fill_color\":\"white\",\"hover_fill_color\":\"lightgray\"}}}}}}}},{\"type\":\"object\",\"name\":\"LassoSelectTool\",\"id\":\"b37b0ab1-5c4d-45ba-a643-1f58a575a596\",\"attributes\":{\"renderers\":\"auto\",\"overlay\":{\"type\":\"object\",\"name\":\"PolyAnnotation\",\"id\":\"f11c24da-80f3-4721-92dd-41b294da98f9\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"xs\":[],\"ys\":[],\"editable\":true,\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"b76e4da6-3cb3-46c3-a599-0283de005f06\"}],\"active_drag\":{\"id\":\"ab4bf321-02a2-4cd5-94a5-690e9e8dae32\"},\"active_scroll\":{\"id\":\"a75e3fce-ac98-4a01-b67b-315061bf428b\"}}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"3bcd8245-4272-45c9-9107-daa567a69f96\",\"attributes\":{\"visible\":false,\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"90e5e518-5bc5-44f8-9193-2b71634f4940\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"31617464-fc9b-4a5e-8c19-f6183d121730\"},\"axis_label\":\"lat\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"3bdff54e-1137-47aa-aba0-2f89fdb0bf31\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"3d1e041e-57c9-4cfb-a522-632639ec5443\",\"attributes\":{\"visible\":false,\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"63524529-fafa-42fc-9083-d4ad44ae602d\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"93480733-03c1-40f2-b0bf-29e5f43866fd\"},\"axis_label\":\"long\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"3bc6f8c9-1113-4203-b8e2-02a888786ae3\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"5774109c-94a7-42f5-962f-dcaef5342e98\",\"attributes\":{\"axis\":{\"id\":\"3d1e041e-57c9-4cfb-a522-632639ec5443\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"0c4951ac-d041-41fa-bfbd-e968612a14ed\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"3bcd8245-4272-45c9-9107-daa567a69f96\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"ColorBar\",\"id\":\"1caed241-341c-4d55-990f-9f58c9b29b27\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BinnedTicker\",\"id\":\"d37453bb-3082-4faf-b2e6-50f52ba709d1\",\"attributes\":{\"mapper\":{\"id\":\"4f7a5df2-eded-4efd-9239-a00a1cda963a\"}}},\"major_label_policy\":{\"type\":\"object\",\"name\":\"NoOverlap\",\"id\":\"6a0d68cf-f291-494d-9bd9-38b7c6d8783f\"},\"label_standoff\":8,\"major_tick_line_color\":\"black\",\"bar_line_color\":\"black\",\"color_mapper\":{\"id\":\"4f7a5df2-eded-4efd-9239-a00a1cda963a\"}}}],\"min_border_top\":10,\"min_border_bottom\":10,\"min_border_left\":10,\"min_border_right\":10,\"output_backend\":\"webgl\",\"hold_render\":false}},0,4,5,8],[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"4beaa702-c2a2-439f-b3ce-436cb5b76bc6\",\"attributes\":{\"subscribed_events\":{\"type\":\"set\",\"entries\":[\"reset\",\"selectiongeometry\"]},\"width\":400,\"height\":480,\"margin\":[5,10],\"sizing_mode\":\"stretch_both\",\"align\":\"start\",\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"de3c7d7f-8aef-434d-b951-36bd692b2d7b\",\"attributes\":{\"name\":\"age\",\"tags\":[[[\"age\",null]],[]],\"start\":-9.6,\"end\":99.6,\"reset_start\":-9.6,\"reset_end\":99.6}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"f25ed264-dfdb-4c3f-8c11-87b6e34e7da9\",\"attributes\":{\"name\":\"Frequency\",\"tags\":[[[\"Frequency\",null]],{\"type\":\"map\",\"entries\":[[\"invert_yaxis\",false],[\"autorange\",false]]}],\"end\":893314.3,\"reset_start\":0.0,\"reset_end\":893314.3}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"22af2720-1281-4eea-bd10-f38038cef844\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"4e083937-45bf-4405-9dc9-544330276fa7\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"224ee003-1111-42fd-8ab4-6b0b69347b9e\",\"attributes\":{\"text\":\"age\",\"text_color\":\"black\",\"text_font_size\":\"12pt\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"c4b10071-38c4-47e4-bc71-c683abdea16b\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"d56604f4-84a1-4095-8bcb-2ad5e5595657\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"fccf764d-d856-49e9-bd7b-67ac23de13f4\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"85807b75-77c4-40ba-82d5-a659a23ff809\"},\"data\":{\"type\":\"map\",\"entries\":[[\"top\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"Lx8KAP93CgCBzgoAxc4KAP3oCgDwKgsAaoMLACVMCwArGgsAHe8KAEUICwDrrgoA63oKANIMCgBe4gkA3J0JAG94CQCdwwkArA0KAD16CgDusgoAohYLAH07CwBqVAsAB7sLAH3KCwDKJwwAgHEMAAw9DABhIgwASz8MAMDuCwB9DgwAVw0MAGfDCwDa1gsAP88LAKLmCwBO6QsA0G0LAEipCgD3fAoA06sKAEzgCgDnEAsAYIoLAP8GDABbaQwABRoMANtjDAAcXQwAjIgMAMSFDABUlAwA53MMAKooDADn3wsABnMLAHb2CgAoswoAEHUKAAMMCgBIqwkAtk4JAD5TCQDFLQkAz+MIAO3rCAAlFAkAc0cJAF3ACQCUgwoAnwwIAPq/BwBIpwcAEgoHAC03BgALhQUA6aUFAHqBBQDgPQUAUd8EAOmCBACTJgQANbQDAJRhAwDcHgMAOs8CAPZ0AgCFEAIASPYHAA==\"},\"shape\":[91],\"dtype\":\"int32\",\"order\":\"little\"}],[\"left\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAA4L8AAAAAAADgPwAAAAAAAPg/AAAAAAAABEAAAAAAAAAMQAAAAAAAABJAAAAAAAAAFkAAAAAAAAAaQAAAAAAAAB5AAAAAAAAAIUAAAAAAAAAjQAAAAAAAACVAAAAAAAAAJ0AAAAAAAAApQAAAAAAAACtAAAAAAAAALUAAAAAAAAAvQAAAAAAAgDBAAAAAAACAMUAAAAAAAIAyQAAAAAAAgDNAAAAAAACANEAAAAAAAIA1QAAAAAAAgDZAAAAAAACAN0AAAAAAAIA4QAAAAAAAgDlAAAAAAACAOkAAAAAAAIA7QAAAAAAAgDxAAAAAAACAPUAAAAAAAIA+QAAAAAAAgD9AAAAAAABAQEAAAAAAAMBAQAAAAAAAQEFAAAAAAADAQUAAAAAAAEBCQAAAAAAAwEJAAAAAAABAQ0AAAAAAAMBDQAAAAAAAQERAAAAAAADAREAAAAAAAEBFQAAAAAAAwEVAAAAAAABARkAAAAAAAMBGQAAAAAAAQEdAAAAAAADAR0AAAAAAAEBIQAAAAAAAwEhAAAAAAABASUAAAAAAAMBJQAAAAAAAQEpAAAAAAADASkAAAAAAAEBLQAAAAAAAwEtAAAAAAABATEAAAAAAAMBMQAAAAAAAQE1AAAAAAADATUAAAAAAAEBOQAAAAAAAwE5AAAAAAABAT0AAAAAAAMBPQAAAAAAAIFBAAAAAAABgUEAAAAAAAKBQQAAAAAAA4FBAAAAAAAAgUUAAAAAAAGBRQAAAAAAAoFFAAAAAAADgUUAAAAAAACBSQAAAAAAAYFJAAAAAAACgUkAAAAAAAOBSQAAAAAAAIFNAAAAAAABgU0AAAAAAAKBTQAAAAAAA4FNAAAAAAAAgVEAAAAAAAGBUQAAAAAAAoFRAAAAAAADgVEAAAAAAACBVQAAAAAAAYFVAAAAAAACgVUAAAAAAAOBVQAAAAAAAIFZAAAAAAABgVkA=\"},\"shape\":[91],\"dtype\":\"float64\",\"order\":\"little\"}],[\"right\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAA4D8AAAAAAAD4PwAAAAAAAARAAAAAAAAADEAAAAAAAAASQAAAAAAAABZAAAAAAAAAGkAAAAAAAAAeQAAAAAAAACFAAAAAAAAAI0AAAAAAAAAlQAAAAAAAACdAAAAAAAAAKUAAAAAAAAArQAAAAAAAAC1AAAAAAAAAL0AAAAAAAIAwQAAAAAAAgDFAAAAAAACAMkAAAAAAAIAzQAAAAAAAgDRAAAAAAACANUAAAAAAAIA2QAAAAAAAgDdAAAAAAACAOEAAAAAAAIA5QAAAAAAAgDpAAAAAAACAO0AAAAAAAIA8QAAAAAAAgD1AAAAAAACAPkAAAAAAAIA/QAAAAAAAQEBAAAAAAADAQEAAAAAAAEBBQAAAAAAAwEFAAAAAAABAQkAAAAAAAMBCQAAAAAAAQENAAAAAAADAQ0AAAAAAAEBEQAAAAAAAwERAAAAAAABARUAAAAAAAMBFQAAAAAAAQEZAAAAAAADARkAAAAAAAEBHQAAAAAAAwEdAAAAAAABASEAAAAAAAMBIQAAAAAAAQElAAAAAAADASUAAAAAAAEBKQAAAAAAAwEpAAAAAAABAS0AAAAAAAMBLQAAAAAAAQExAAAAAAADATEAAAAAAAEBNQAAAAAAAwE1AAAAAAABATkAAAAAAAMBOQAAAAAAAQE9AAAAAAADAT0AAAAAAACBQQAAAAAAAYFBAAAAAAACgUEAAAAAAAOBQQAAAAAAAIFFAAAAAAABgUUAAAAAAAKBRQAAAAAAA4FFAAAAAAAAgUkAAAAAAAGBSQAAAAAAAoFJAAAAAAADgUkAAAAAAACBTQAAAAAAAYFNAAAAAAACgU0AAAAAAAOBTQAAAAAAAIFRAAAAAAABgVEAAAAAAAKBUQAAAAAAA4FRAAAAAAAAgVUAAAAAAAGBVQAAAAAAAoFVAAAAAAADgVUAAAAAAACBWQAAAAAAAYFZAAAAAAACgVkA=\"},\"shape\":[91],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"5b2bcb24-ca2d-48a2-83b6-3825337416c3\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"98121cec-f06f-4b03-b85e-e3611e9b7563\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Quad\",\"id\":\"9ff3d654-48b9-4daa-8d07-dd4d3bc7136b\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"left\":{\"type\":\"field\",\"field\":\"left\"},\"right\":{\"type\":\"field\",\"field\":\"right\"},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"top\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"selection_glyph\":{\"type\":\"object\",\"name\":\"Quad\",\"id\":\"6e2839c2-c8d0-4b84-9c8e-8f18980e6451\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"left\":{\"type\":\"field\",\"field\":\"left\"},\"right\":{\"type\":\"field\",\"field\":\"right\"},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"top\"},\"line_color\":{\"type\":\"value\",\"value\":\"black\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"line_width\":{\"type\":\"value\",\"value\":1},\"line_join\":{\"type\":\"value\",\"value\":\"bevel\"},\"line_cap\":{\"type\":\"value\",\"value\":\"butt\"},\"line_dash\":{\"type\":\"value\",\"value\":[]},\"line_dash_offset\":{\"type\":\"value\",\"value\":0},\"fill_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_scale\":{\"type\":\"value\",\"value\":12.0},\"hatch_pattern\":{\"type\":\"value\",\"value\":null},\"hatch_weight\":{\"type\":\"value\",\"value\":1.0}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Quad\",\"id\":\"38a8b1cc-9e7e-45f1-93d5-381af65464ef\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"left\":{\"type\":\"field\",\"field\":\"left\"},\"right\":{\"type\":\"field\",\"field\":\"right\"},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"top\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Quad\",\"id\":\"94e74c2f-3e29-44d7-b5c1-1f6b386d494a\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"left\":{\"type\":\"field\",\"field\":\"left\"},\"right\":{\"type\":\"field\",\"field\":\"right\"},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"top\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"value\",\"value\":\"#30a2da\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"34235c71-6190-435f-8c10-526e4170c99b\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"5890d10d-5680-4e47-9c84-7e395cf76005\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"0e64e192-1318-40f0-829c-ec7af596778d\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"f2c4563a-47e2-4dae-b441-c1ab660dda7a\"},\"data\":{\"type\":\"map\",\"entries\":[[\"top\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"Lx8KAP93CgCBzgoAxc4KAP3oCgDwKgsAaoMLACVMCwArGgsAHe8KAEUICwDrrgoA63oKANIMCgBe4gkA3J0JAG94CQCdwwkArA0KAD16CgDusgoAohYLAH07CwBqVAsAB7sLAH3KCwDKJwwAgHEMAAw9DABhIgwASz8MAMDuCwB9DgwAVw0MAGfDCwDa1gsAP88LAKLmCwBO6QsA0G0LAEipCgD3fAoA06sKAEzgCgDnEAsAYIoLAP8GDABbaQwABRoMANtjDAAcXQwAjIgMAMSFDABUlAwA53MMAKooDADn3wsABnMLAHb2CgAoswoAEHUKAAMMCgBIqwkAtk4JAD5TCQDFLQkAz+MIAO3rCAAlFAkAc0cJAF3ACQCUgwoAnwwIAPq/BwBIpwcAEgoHAC03BgALhQUA6aUFAHqBBQDgPQUAUd8EAOmCBACTJgQANbQDAJRhAwDcHgMAOs8CAPZ0AgCFEAIASPYHAA==\"},\"shape\":[91],\"dtype\":\"int32\",\"order\":\"little\"}],[\"left\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAA4L8AAAAAAADgPwAAAAAAAPg/AAAAAAAABEAAAAAAAAAMQAAAAAAAABJAAAAAAAAAFkAAAAAAAAAaQAAAAAAAAB5AAAAAAAAAIUAAAAAAAAAjQAAAAAAAACVAAAAAAAAAJ0AAAAAAAAApQAAAAAAAACtAAAAAAAAALUAAAAAAAAAvQAAAAAAAgDBAAAAAAACAMUAAAAAAAIAyQAAAAAAAgDNAAAAAAACANEAAAAAAAIA1QAAAAAAAgDZAAAAAAACAN0AAAAAAAIA4QAAAAAAAgDlAAAAAAACAOkAAAAAAAIA7QAAAAAAAgDxAAAAAAACAPUAAAAAAAIA+QAAAAAAAgD9AAAAAAABAQEAAAAAAAMBAQAAAAAAAQEFAAAAAAADAQUAAAAAAAEBCQAAAAAAAwEJAAAAAAABAQ0AAAAAAAMBDQAAAAAAAQERAAAAAAADAREAAAAAAAEBFQAAAAAAAwEVAAAAAAABARkAAAAAAAMBGQAAAAAAAQEdAAAAAAADAR0AAAAAAAEBIQAAAAAAAwEhAAAAAAABASUAAAAAAAMBJQAAAAAAAQEpAAAAAAADASkAAAAAAAEBLQAAAAAAAwEtAAAAAAABATEAAAAAAAMBMQAAAAAAAQE1AAAAAAADATUAAAAAAAEBOQAAAAAAAwE5AAAAAAABAT0AAAAAAAMBPQAAAAAAAIFBAAAAAAABgUEAAAAAAAKBQQAAAAAAA4FBAAAAAAAAgUUAAAAAAAGBRQAAAAAAAoFFAAAAAAADgUUAAAAAAACBSQAAAAAAAYFJAAAAAAACgUkAAAAAAAOBSQAAAAAAAIFNAAAAAAABgU0AAAAAAAKBTQAAAAAAA4FNAAAAAAAAgVEAAAAAAAGBUQAAAAAAAoFRAAAAAAADgVEAAAAAAACBVQAAAAAAAYFVAAAAAAACgVUAAAAAAAOBVQAAAAAAAIFZAAAAAAABgVkA=\"},\"shape\":[91],\"dtype\":\"float64\",\"order\":\"little\"}],[\"right\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAA4D8AAAAAAAD4PwAAAAAAAARAAAAAAAAADEAAAAAAAAASQAAAAAAAABZAAAAAAAAAGkAAAAAAAAAeQAAAAAAAACFAAAAAAAAAI0AAAAAAAAAlQAAAAAAAACdAAAAAAAAAKUAAAAAAAAArQAAAAAAAAC1AAAAAAAAAL0AAAAAAAIAwQAAAAAAAgDFAAAAAAACAMkAAAAAAAIAzQAAAAAAAgDRAAAAAAACANUAAAAAAAIA2QAAAAAAAgDdAAAAAAACAOEAAAAAAAIA5QAAAAAAAgDpAAAAAAACAO0AAAAAAAIA8QAAAAAAAgD1AAAAAAACAPkAAAAAAAIA/QAAAAAAAQEBAAAAAAADAQEAAAAAAAEBBQAAAAAAAwEFAAAAAAABAQkAAAAAAAMBCQAAAAAAAQENAAAAAAADAQ0AAAAAAAEBEQAAAAAAAwERAAAAAAABARUAAAAAAAMBFQAAAAAAAQEZAAAAAAADARkAAAAAAAEBHQAAAAAAAwEdAAAAAAABASEAAAAAAAMBIQAAAAAAAQElAAAAAAADASUAAAAAAAEBKQAAAAAAAwEpAAAAAAABAS0AAAAAAAMBLQAAAAAAAQExAAAAAAADATEAAAAAAAEBNQAAAAAAAwE1AAAAAAABATkAAAAAAAMBOQAAAAAAAQE9AAAAAAADAT0AAAAAAACBQQAAAAAAAYFBAAAAAAACgUEAAAAAAAOBQQAAAAAAAIFFAAAAAAABgUUAAAAAAAKBRQAAAAAAA4FFAAAAAAAAgUkAAAAAAAGBSQAAAAAAAoFJAAAAAAADgUkAAAAAAACBTQAAAAAAAYFNAAAAAAACgU0AAAAAAAOBTQAAAAAAAIFRAAAAAAABgVEAAAAAAAKBUQAAAAAAA4FRAAAAAAAAgVUAAAAAAAGBVQAAAAAAAoFVAAAAAAADgVUAAAAAAACBWQAAAAAAAYFZAAAAAAACgVkA=\"},\"shape\":[91],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"8f2c93a3-e832-4ac0-8d56-7003715bca95\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"0197a006-da38-436a-8a18-a7387d5fecd2\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Quad\",\"id\":\"c60093eb-c36b-4d29-b78a-884b4ff54813\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"left\":{\"type\":\"field\",\"field\":\"left\"},\"right\":{\"type\":\"field\",\"field\":\"right\"},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"top\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#4292c6\"},\"hatch_color\":{\"type\":\"value\",\"value\":\"#fc4f30\"}}},\"selection_glyph\":{\"type\":\"object\",\"name\":\"Quad\",\"id\":\"4eb4ccc1-8a5d-477e-993f-ce2c560f75cb\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"left\":{\"type\":\"field\",\"field\":\"left\"},\"right\":{\"type\":\"field\",\"field\":\"right\"},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"top\"},\"line_color\":{\"type\":\"value\",\"value\":\"black\"},\"line_alpha\":{\"type\":\"value\",\"value\":1.0},\"line_width\":{\"type\":\"value\",\"value\":1},\"line_join\":{\"type\":\"value\",\"value\":\"bevel\"},\"line_cap\":{\"type\":\"value\",\"value\":\"butt\"},\"line_dash\":{\"type\":\"value\",\"value\":[]},\"line_dash_offset\":{\"type\":\"value\",\"value\":0},\"fill_color\":{\"type\":\"value\",\"value\":\"#4292c6\"},\"fill_alpha\":{\"type\":\"value\",\"value\":1.0},\"hatch_color\":{\"type\":\"value\",\"value\":\"#fc4f30\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":1.0},\"hatch_scale\":{\"type\":\"value\",\"value\":12.0},\"hatch_pattern\":{\"type\":\"value\",\"value\":null},\"hatch_weight\":{\"type\":\"value\",\"value\":1.0}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Quad\",\"id\":\"7ea2da59-7164-4b88-9da9-c9ab7b94664a\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"left\":{\"type\":\"field\",\"field\":\"left\"},\"right\":{\"type\":\"field\",\"field\":\"right\"},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"top\"},\"fill_color\":{\"type\":\"value\",\"value\":\"#4292c6\"},\"hatch_color\":{\"type\":\"value\",\"value\":\"#fc4f30\"}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Quad\",\"id\":\"773c4920-7a42-4548-a11f-d242588911e9\",\"attributes\":{\"tags\":[\"apply_ranges\"],\"left\":{\"type\":\"field\",\"field\":\"left\"},\"right\":{\"type\":\"field\",\"field\":\"right\"},\"bottom\":{\"type\":\"value\",\"value\":0},\"top\":{\"type\":\"field\",\"field\":\"top\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"value\",\"value\":\"#4292c6\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_color\":{\"type\":\"value\",\"value\":\"#fc4f30\"},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"177285b3-11d1-4089-adfe-d5ae4df1f31f\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"83b1cf28-28be-46b9-bd4a-7aad883731f5\",\"attributes\":{\"tags\":[\"hv_created\"],\"renderers\":\"auto\",\"zoom_together\":\"none\"}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"6cf7adbf-00ed-498d-b501-e397102957d8\"},{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"0f1c245c-6400-47a8-8edf-305962926696\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"237c3f47-ffa7-4d57-b8b6-0e4d3b588690\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"8687658b-8f03-4aed-a212-855e0101ef2b\",\"attributes\":{\"syncable\":false,\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"handles\":{\"type\":\"object\",\"name\":\"BoxInteractionHandles\",\"id\":\"e9f508db-ff38-4e57-a020-7ae9632d5918\",\"attributes\":{\"all\":{\"type\":\"object\",\"name\":\"AreaVisuals\",\"id\":\"a50a3920-2719-4617-b773-7c91065db1f3\",\"attributes\":{\"fill_color\":\"white\",\"hover_fill_color\":\"lightgray\"}}}}}}}},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"694f10f9-2d7d-4135-b366-b35607713bc2\"},{\"type\":\"object\",\"name\":\"BoxSelectTool\",\"id\":\"1d991191-8303-441a-ab00-8d286d686114\",\"attributes\":{\"renderers\":\"auto\",\"dimensions\":\"width\",\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"e89642f2-d8d5-4659-8cd7-37ddaab3ae51\",\"attributes\":{\"syncable\":false,\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"editable\":true,\"handles\":{\"type\":\"object\",\"name\":\"BoxInteractionHandles\",\"id\":\"8becd2c4-b082-466a-a611-03bb86d214f7\",\"attributes\":{\"all\":{\"type\":\"object\",\"name\":\"AreaVisuals\",\"id\":\"c73778a7-5b9c-45db-8f6c-150212e5a3bc\",\"attributes\":{\"fill_color\":\"white\",\"hover_fill_color\":\"lightgray\"}}}}}}}}],\"active_drag\":{\"id\":\"1d991191-8303-441a-ab00-8d286d686114\"}}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"dcf85617-96dd-4b71-bb64-5301b8b310b4\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"ddf3b2a7-e6d7-4719-8852-7b420ff9e06a\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"0f436b85-5822-4263-a14f-aee48ae4f32e\"},\"axis_label\":\"frequency\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"80a7d917-0340-40bc-bb73-6d7ddd4d4829\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"7b8eebc1-a943-4822-aa30-b649f3a2aa73\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"ae6c2094-ad5a-4549-b785-009c030912fa\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"58032d96-2211-479a-b6fe-f61478d2b99a\"},\"axis_label\":\"age\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"5d6f7215-4614-45e4-a0c4-b5c3d95e0e0a\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"4a605d7b-c7dd-4907-bfe4-a3b21162e216\",\"attributes\":{\"axis\":{\"id\":\"7b8eebc1-a943-4822-aa30-b649f3a2aa73\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"8c1f7bde-5e54-44ca-b1d4-370ef5edf5ef\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"dcf85617-96dd-4b71-bb64-5301b8b310b4\"},\"grid_line_color\":null}}],\"min_border_top\":10,\"min_border_bottom\":10,\"min_border_left\":10,\"min_border_right\":10,\"output_backend\":\"webgl\",\"hold_render\":false}},2,0,3,4]]}},0,2,5,10],[{\"type\":\"object\",\"name\":\"panel.models.layout.Column\",\"id\":\"bc42b05b-99d1-445a-b0e8-b6551fd784d7\",\"attributes\":{\"name\":\"WidgetBox00308\",\"css_classes\":[\"panel-widget-box\"],\"styles\":{\"type\":\"map\",\"entries\":[[\"border-color\",\"#888888\"]]},\"stylesheets\":[\"\\n:host(.pn-loading):before, .pn-loading:before {\\n  background-color: #c3c3c3;\\n  mask-size: auto calc(min(50%, 400px));\\n  -webkit-mask-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"af8ec279-6516-412a-85c1-e630e8a73670\"},\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\",\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\",\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\",{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"0b576859-f8b8-4d2e-b7d4-02d034b64433\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.5.4/dist/css/widgetbox.css\"}},{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"eb9976a6-40c1-43b4-aeb8-eeca072ba5ae\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.5.4/dist/css/listpanel.css\"}},{\"id\":\"447be690-c979-4a42-8994-7f29f7ae3469\"},{\"id\":\"5a8b8bf1-32dd-4d1d-8a8c-d9fa2004434e\"}],\"margin\":0,\"sizing_mode\":\"stretch_width\",\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"panel.models.markup.HTML\",\"id\":\"05c6567f-2153-4e08-97b3-a2c2f2583b6a\",\"attributes\":{\"css_classes\":[\"indicator\"],\"stylesheets\":[\"\\n:host(.pn-loading):before, .pn-loading:before {\\n  background-color: #c3c3c3;\\n  mask-size: auto calc(min(50%, 400px));\\n  -webkit-mask-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"af8ec279-6516-412a-85c1-e630e8a73670\"},\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\",\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\",\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\",{\"id\":\"447be690-c979-4a42-8994-7f29f7ae3469\"},{\"id\":\"5a8b8bf1-32dd-4d1d-8a8c-d9fa2004434e\"}],\"margin\":[5,10],\"sizing_mode\":\"stretch_width\",\"align\":\"start\",\"text\":\"&lt;div style=&quot;font-size: 14pt; color: #2B2B2B&quot;&gt;Datapoints Selected&lt;/div&gt;\\n&lt;div style=&quot;font-size: 18pt; color: #2B2B2B&quot;&gt;58,479,894&lt;/div&gt;\"}},{\"type\":\"object\",\"name\":\"panel.models.widgets.Progress\",\"id\":\"9e8dcdc7-1967-428a-9ad6-0f0e144e2500\",\"attributes\":{\"styles\":{\"type\":\"map\",\"entries\":[[\"--success-bg-color\",\"#4292c6\"]]},\"stylesheets\":[\"\\n:host(.pn-loading):before, .pn-loading:before {\\n  background-color: #c3c3c3;\\n  mask-size: auto calc(min(50%, 400px));\\n  -webkit-mask-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"af8ec279-6516-412a-85c1-e630e8a73670\"},\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\",\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\",\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\",{\"type\":\"object\",\"name\":\"ImportedStyleSheet\",\"id\":\"71016a2e-94bf-4fb4-a7bd-2a264b78e189\",\"attributes\":{\"url\":\"https://cdn.holoviz.org/panel/1.5.4/dist/css/progress.css\"}},{\"id\":\"447be690-c979-4a42-8994-7f29f7ae3469\"},{\"id\":\"5a8b8bf1-32dd-4d1d-8a8c-d9fa2004434e\"}],\"width\":300,\"margin\":[5,10],\"sizing_mode\":\"stretch_width\",\"align\":\"start\",\"bar_color\":\"success\",\"value\":100}}]}},0,0,1,2],[{\"type\":\"object\",\"name\":\"panel.models.layout.Column\",\"id\":\"da5f4e22-fc91-4bd3-a9a9-c41400bcf520\",\"attributes\":{\"name\":\"Column00467\",\"stylesheets\":[\"\\n:host(.pn-loading):before, .pn-loading:before {\\n  background-color: #c3c3c3;\\n  mask-size: auto calc(min(50%, 400px));\\n  -webkit-mask-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"af8ec279-6516-412a-85c1-e630e8a73670\"},\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\",\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\",\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\",{\"id\":\"eb9976a6-40c1-43b4-aeb8-eeca072ba5ae\"},{\"id\":\"447be690-c979-4a42-8994-7f29f7ae3469\"},{\"id\":\"5a8b8bf1-32dd-4d1d-8a8c-d9fa2004434e\"}],\"min_height\":500,\"margin\":0,\"sizing_mode\":\"scale_width\",\"align\":\"start\",\"children\":[{\"type\":\"object\",\"name\":\"MultiChoice\",\"id\":\"2c4cbd3c-bdd2-4143-a4cc-33ce1f810e7e\",\"attributes\":{\"styles\":{\"type\":\"map\",\"entries\":[[\"color\",\"#2B2B2B\"]]},\"stylesheets\":[\"\\n:host(.pn-loading):before, .pn-loading:before {\\n  background-color: #c3c3c3;\\n  mask-size: auto calc(min(50%, 400px));\\n  -webkit-mask-size: auto calc(min(50%, 400px));\\n}\",{\"id\":\"af8ec279-6516-412a-85c1-e630e8a73670\"},\"\\n.dataframe table{\\n  border: none;\\n}\\n\\n.panel-df table{\\n    width: 100%;\\n    border-collapse: collapse;\\n    border: none;\\n}\\n.panel-df td{\\n    white-space: nowrap;\\n    overflow: auto;\\n    text-overflow: ellipsis;\\n}\\n\",\"\\n.multi-select{\\n    color: white;\\n    z-index: 100;\\n    background: rgba(44,43,43,0.5);\\n    border-radius: 1px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n.multi-select > .bk {\\n    padding: 5px;\\n    width: 120px !important;\\n    height: 30px !important;\\n}\\n\\n.deck-chart {\\n    z-index: 10;\\n    position: initial !important;\\n}\\n\",\"\\n.center-header {\\n    text-align: center\\n}\\n.bk-input-group {\\n    padding: 10px;\\n}\\n#sidebar {\\n    padding-top: 10px;\\n}\\n.custom-widget-box {\\n    margin-top: 20px;\\n    padding: 5px;\\n    border: None !important;\\n}\\n.custom-widget-box > p {\\n    margin: 0px;\\n}\\n.bk-input-group {\\n    color: None !important;\\n}\\n.indicator {\\n    text-align: center;\\n}\\n.widget-card {\\n    margin: 5px 10px;\\n}\\n.number-card {\\n    margin: 5px 10px;\\n    text-align: center;\\n}\\n.number-card-value {\\n    width: 100%;\\n    margin: 0px;\\n}\\n\",{\"id\":\"447be690-c979-4a42-8994-7f29f7ae3469\"},{\"id\":\"5a8b8bf1-32dd-4d1d-8a8c-d9fa2004434e\"},\"\\n                .choices__inner .choices__item.solid {\\n                    background-color: #4292c6;\\n                    border-color: #4292c6;\\n                }\\n                .choices__inner, .choices__list--dropdown,\\n                .choices__list[aria-expanded]{\\n                    border-color: #888888 !important;\\n                }\\n                .is-highlighted {\\n                    background-color: #4292c6\\n                    !important;\\n                    color: #2B2B2B !important;\\n                }\\n            \"],\"width\":300,\"margin\":[5,10],\"sizing_mode\":\"scale_width\",\"align\":\"start\",\"title\":\"county\",\"options\":[\"DARLINGTON\",\"COUNTY DURHAM\",\"HARTLEPOOL\",\"MIDDLESBROUGH\",\"NORTHUMBERLAND\",\"REDCAR AND CLEVELAND\",\"STOCKTON-ON-TEES\",\"GATESHEAD\",\"NEWCASTLE UPON TYNE\",\"NORTH TYNESIDE\",\"SOUTH TYNESIDE\",\"SUNDERLAND\",\"BLACKBURN WITH DARWEN\",\"BLACKPOOL\",\"CHESHIRE EAST\",\"CHESHIRE WEST AND CHESTER\",\"HALTON\",\"WARRINGTON\",\"CUMBRIA\",\"BOLTON\",\"BURY\",\"MANCHESTER\",\"OLDHAM\",\"ROCHDALE\",\"SALFORD\",\"STOCKPORT\",\"TAMESIDE\",\"TRAFFORD\",\"WIGAN\",\"LANCASHIRE\",\"KNOWSLEY\",\"LIVERPOOL\",\"SEFTON\",\"ST. HELENS\",\"WIRRAL\",\"EAST RIDING OF YORKSHIRE\",\"KINGSTON UPON HULL, CITY OF\",\"NORTH EAST LINCOLNSHIRE\",\"NORTH LINCOLNSHIRE\",\"YORK\",\"NORTH YORKSHIRE\",\"BARNSLEY\",\"DONCASTER\",\"ROTHERHAM\",\"SHEFFIELD\",\"BRADFORD\",\"CALDERDALE\",\"KIRKLEES\",\"LEEDS\",\"WAKEFIELD\",\"DERBY\",\"LEICESTER\",\"NOTTINGHAM\",\"RUTLAND\",\"DERBYSHIRE\",\"LEICESTERSHIRE\",\"LINCOLNSHIRE\",\"NORTHAMPTONSHIRE\",\"NOTTINGHAMSHIRE\",\"HEREFORDSHIRE, COUNTY OF\",\"SHROPSHIRE\",\"STOKE-ON-TRENT\",\"TELFORD AND WREKIN\",\"STAFFORDSHIRE\",\"WARWICKSHIRE\",\"BIRMINGHAM\",\"COVENTRY\",\"DUDLEY\",\"SANDWELL\",\"SOLIHULL\",\"WALSALL\",\"WOLVERHAMPTON\",\"WORCESTERSHIRE\",\"BEDFORD\",\"CENTRAL BEDFORDSHIRE\",\"LUTON\",\"PETERBOROUGH\",\"SOUTHEND-ON-SEA\",\"THURROCK\",\"CAMBRIDGESHIRE\",\"ESSEX\",\"HERTFORDSHIRE\",\"NORFOLK\",\"SUFFOLK\",\"CAMDEN\",\"CITY OF LONDON\",\"HACKNEY\",\"HAMMERSMITH AND FULHAM\",\"HARINGEY\",\"ISLINGTON\",\"KENSINGTON AND CHELSEA\",\"LAMBETH\",\"LEWISHAM\",\"NEWHAM\",\"SOUTHWARK\",\"TOWER HAMLETS\",\"WANDSWORTH\",\"WESTMINSTER\",\"BARKING AND DAGENHAM\",\"BARNET\",\"BEXLEY\",\"BRENT\",\"BROMLEY\",\"CROYDON\",\"EALING\",\"ENFIELD\",\"GREENWICH\",\"HARROW\",\"HAVERING\",\"HILLINGDON\",\"HOUNSLOW\",\"KINGSTON UPON THAMES\",\"MERTON\",\"REDBRIDGE\",\"RICHMOND UPON THAMES\",\"SUTTON\",\"WALTHAM FOREST\",\"BRACKNELL FOREST\",\"BRIGHTON AND HOVE\",\"ISLE OF WIGHT\",\"MEDWAY\",\"MILTON KEYNES\",\"PORTSMOUTH\",\"READING\",\"SLOUGH\",\"SOUTHAMPTON\",\"WEST BERKSHIRE\",\"WINDSOR AND MAIDENHEAD\",\"WOKINGHAM\",\"BUCKINGHAMSHIRE\",\"EAST SUSSEX\",\"HAMPSHIRE\",\"KENT\",\"OXFORDSHIRE\",\"SURREY\",\"WEST SUSSEX\",\"BATH AND NORTH EAST SOMERSET\",\"BRISTOL, CITY OF\",\"CORNWALL\",\"ISLES OF SCILLY\",\"NORTH SOMERSET\",\"PLYMOUTH\",\"SOUTH GLOUCESTERSHIRE\",\"SWINDON\",\"TORBAY\",\"WILTSHIRE\",\"DEVON\",\"DORSET\",\"GLOUCESTERSHIRE\",\"SOMERSET\",\"ISLE OF ANGLESEY\",\"GWYNEDD\",\"CONWY\",\"DENBIGHSHIRE\",\"FLINTSHIRE\",\"WREXHAM\",\"POWYS\",\"CEREDIGION\",\"PEMBROKESHIRE\",\"CARMARTHENSHIRE\",\"SWANSEA\",\"NEATH PORT TALBOT\",\"BRIDGEND\",\"VALE OF GLAMORGAN\",\"CARDIFF\",\"MERTHYR TYDFIL\",\"CAERPHILLY\",\"BLAENAU GWENT\",\"TORFAEN\",\"MONMOUTHSHIRE\",\"NEWPORT\"],\"placeholder\":\"\"}}]}},1,0,4,2]]}},{\"type\":\"object\",\"name\":\"panel.models.comm_manager.CommManager\",\"id\":\"33c2c855-1a2b-49ef-b543-ecabe6fe28d4\",\"attributes\":{\"plot_id\":\"d8fb88cc-1bae-4a54-a455-83ab4e59be12\",\"comm_id\":\"6c07ff8b7c2f480fb5795cbeff95a0f4\",\"client_comm_id\":\"f9a5bd4d5572484cbe5ad6bf9c777e75\"}}],\"defs\":[{\"type\":\"model\",\"name\":\"ReactiveHTML1\"},{\"type\":\"model\",\"name\":\"FlexBox1\",\"properties\":[{\"name\":\"align_content\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"align_items\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"flex_direction\",\"kind\":\"Any\",\"default\":\"row\"},{\"name\":\"flex_wrap\",\"kind\":\"Any\",\"default\":\"wrap\"},{\"name\":\"gap\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"justify_content\",\"kind\":\"Any\",\"default\":\"flex-start\"}]},{\"type\":\"model\",\"name\":\"FloatPanel1\",\"properties\":[{\"name\":\"config\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"contained\",\"kind\":\"Any\",\"default\":true},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"right-top\"},{\"name\":\"offsetx\",\"kind\":\"Any\",\"default\":null},{\"name\":\"offsety\",\"kind\":\"Any\",\"default\":null},{\"name\":\"theme\",\"kind\":\"Any\",\"default\":\"primary\"},{\"name\":\"status\",\"kind\":\"Any\",\"default\":\"normalized\"}]},{\"type\":\"model\",\"name\":\"GridStack1\",\"properties\":[{\"name\":\"mode\",\"kind\":\"Any\",\"default\":\"warn\"},{\"name\":\"ncols\",\"kind\":\"Any\",\"default\":null},{\"name\":\"nrows\",\"kind\":\"Any\",\"default\":null},{\"name\":\"allow_resize\",\"kind\":\"Any\",\"default\":true},{\"name\":\"allow_drag\",\"kind\":\"Any\",\"default\":true},{\"name\":\"state\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"drag1\",\"properties\":[{\"name\":\"slider_width\",\"kind\":\"Any\",\"default\":5},{\"name\":\"slider_color\",\"kind\":\"Any\",\"default\":\"black\"},{\"name\":\"value\",\"kind\":\"Any\",\"default\":50}]},{\"type\":\"model\",\"name\":\"click1\",\"properties\":[{\"name\":\"terminal_output\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"debug_name\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"clears\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"FastWrapper1\",\"properties\":[{\"name\":\"object\",\"kind\":\"Any\",\"default\":null},{\"name\":\"style\",\"kind\":\"Any\",\"default\":null}]},{\"type\":\"model\",\"name\":\"NotificationAreaBase1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"NotificationArea1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"notifications\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0},{\"name\":\"types\",\"kind\":\"Any\",\"default\":[{\"type\":\"map\",\"entries\":[[\"type\",\"warning\"],[\"background\",\"#ffc107\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-exclamation-triangle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]},{\"type\":\"map\",\"entries\":[[\"type\",\"info\"],[\"background\",\"#007bff\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-info-circle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]}]}]},{\"type\":\"model\",\"name\":\"Notification\",\"properties\":[{\"name\":\"background\",\"kind\":\"Any\",\"default\":null},{\"name\":\"duration\",\"kind\":\"Any\",\"default\":3000},{\"name\":\"icon\",\"kind\":\"Any\",\"default\":null},{\"name\":\"message\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"notification_type\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_destroyed\",\"kind\":\"Any\",\"default\":false}]},{\"type\":\"model\",\"name\":\"TemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"BootstrapTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"TemplateEditor1\",\"properties\":[{\"name\":\"layout\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"MaterialTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"ReactiveESM1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"JSComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"ReactComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"AnyWidgetComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"request_value1\",\"properties\":[{\"name\":\"fill\",\"kind\":\"Any\",\"default\":\"none\"},{\"name\":\"_synced\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_request_sync\",\"kind\":\"Any\",\"default\":0}]}]}};\n",
       "  var render_items = [{\"docid\":\"ac83bbab-1fc2-45fd-bf74-8a83d9396f29\",\"roots\":{\"d8fb88cc-1bae-4a54-a455-83ab4e59be12\":\"ae386224-877d-4305-82dd-7dc4bfb77cfa\"},\"root_ids\":[\"d8fb88cc-1bae-4a54-a455-83ab4e59be12\"]}];\n",
       "  var docs = Object.values(docs_json)\n",
       "  if (!docs) {\n",
       "    return\n",
       "  }\n",
       "  const py_version = docs[0].version.replace('rc', '-rc.').replace('.dev', '-dev.')\n",
       "  async function embed_document(root) {\n",
       "    var Bokeh = get_bokeh(root)\n",
       "    await Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
       "    for (const render_item of render_items) {\n",
       "      for (const root_id of render_item.root_ids) {\n",
       "\tconst id_el = document.getElementById(root_id)\n",
       "\tif (id_el.children.length && id_el.children[0].hasAttribute('data-root-id')) {\n",
       "\t  const root_el = id_el.children[0]\n",
       "\t  root_el.id = root_el.id + '-rendered'\n",
       "\t  for (const child of root_el.children) {\n",
       "            // Ensure JupyterLab does not capture keyboard shortcuts\n",
       "            // see: https://jupyterlab.readthedocs.io/en/4.1.x/extension/notebook.html#keyboard-interaction-model\n",
       "\t    child.setAttribute('data-lm-suppress-shortcuts', 'true')\n",
       "\t  }\n",
       "\t}\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "  function get_bokeh(root) {\n",
       "    if (root.Bokeh === undefined) {\n",
       "      return null\n",
       "    } else if (root.Bokeh.version !== py_version) {\n",
       "      if (root.Bokeh.versions === undefined || !root.Bokeh.versions.has(py_version)) {\n",
       "\treturn null\n",
       "      }\n",
       "      return root.Bokeh.versions.get(py_version);\n",
       "    } else if (root.Bokeh.version === py_version) {\n",
       "      return root.Bokeh\n",
       "    }\n",
       "    return null\n",
       "  }\n",
       "  function is_loaded(root) {\n",
       "    var Bokeh = get_bokeh(root)\n",
       "    return (Bokeh != null && Bokeh.Panel !== undefined && ( root.deck !== undefined) && ( root.deck !== undefined))\n",
       "  }\n",
       "  if (is_loaded(root)) {\n",
       "    embed_document(root);\n",
       "  } else {\n",
       "    var attempts = 0;\n",
       "    var timer = setInterval(function(root) {\n",
       "      if (is_loaded(root)) {\n",
       "        clearInterval(timer);\n",
       "        embed_document(root);\n",
       "      } else if (document.readyState == \"complete\") {\n",
       "        attempts++;\n",
       "        if (attempts > 200) {\n",
       "          clearInterval(timer);\n",
       "\t  var Bokeh = get_bokeh(root)\n",
       "\t  if (Bokeh == null || Bokeh.Panel == null) {\n",
       "            console.warn(\"Panel: ERROR: Unable to run Panel code because Bokeh or Panel library is missing\");\n",
       "\t  } else {\n",
       "\t    console.warn(\"Panel: WARNING: Attempting to render but not all required libraries could be resolved.\")\n",
       "\t    embed_document(root)\n",
       "\t  }\n",
       "        }\n",
       "      }\n",
       "    }, 25, root)\n",
       "  }\n",
       "})(window);</script>"
      ],
      "text/plain": [
       "GridSpec(ncols=12, nrows=5)\n",
       "    [0] GridSpec(height=800, ncols=12, nrows=5, sizing_mode='fixed', width=1200)\n",
       "        [0] HoloViews(DynamicMap, height=320, sizing_mode='stretch_both', width=400)\n",
       "        [1] HoloViews(DynamicMap, height=800, sizing_mode='stretch_both', width=800)\n",
       "        [2] HoloViews(DynamicMap, height=480, sizing_mode='stretch_both', width=400)\n",
       "    [1] WidgetBox(styles={'border-color': '...})\n",
       "        [0] Number(css_classes=['indicator'], default_color='#2B2B2B', font_size='18pt', format='{value:,}', name='Datapoints Selected', sizing_mode='stretch_width', title_size='14pt', value=58479894)\n",
       "        [1] Progress(sizing_mode='stretch_width', styles={'--success-bg-color': '...}, value=100)\n",
       "    [2] Column(min_height=500, sizing_mode='stretch_width')\n",
       "        [0] MultiChoice(name='county', options={<pyarrow.StringScalar: 'D...}, sizing_mode='scale_width', styles={'color': '#2B2B2B'}, stylesheets=['\\n                .choic...])"
      ]
     },
     "execution_count": 11,
     "metadata": {
      "application/vnd.holoviews_exec.v0+json": {
       "id": "d8fb88cc-1bae-4a54-a455-83ab4e59be12"
      }
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# create multiselect widget\n",
    "county_widget = cxf.charts.panel_widgets.multi_select('county', label_map=county_map)\n",
    "\n",
    "# define layout\n",
    "dash = cxf_data.dashboard(charts=[chart_2, scatter_chart, chart_3],sidebar=[county_widget], theme=cxf.themes.dark, data_size_widget=True, layout_array=layout_array)\n",
    "\n",
    "dash.app()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08b9ca80-2469-4f49-8781-1910bdce41bd",
   "metadata": {},
   "source": [
    "## Other Libraries ##\n",
    "* Plotly:\n",
    "    * https://dash.plotly.com/holoviews#gpu-accelerating-datashader-and-linked-selections-with-rapids\n",
    "    * https://developer.nvidia.com/blog/making-a-plotly-dash-census-viz-powered-by-rapids/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e9d7f104-879d-4784-bf47-541fa4cda445",
   "metadata": {},
   "outputs": [],
   "source": [
    "import IPython\n",
    "app = IPython.Application.instance()\n",
    "app.kernel.do_shutdown(True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9dc3b5a1-051f-4e4c-b830-1dbf066eb622",
   "metadata": {},
   "source": [
    "**Well Done!** Let's move to the [next notebook](1-07_etl.ipynb). "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89ffb0bd-9cbf-4f75-affd-0f614e4074e3",
   "metadata": {},
   "source": [
    "<img src=\"./images/DLI_Header.png\" width=400/>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.10.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
