{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e4bed248-56f0-4852-b98e-ff612d222ffb",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import holoviews as hv\n",
    "import panel as pn\n",
    "\n",
    "from colorcet import bmy\n",
    "\n",
    "pn.extension('tabulator', template='fast')\n",
    "import hvplot.pandas"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df3cf9ed-a109-410b-9955-0dcb42d06eac",
   "metadata": {},
   "source": [
    "## Create intro"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a2d16e0e-9dd5-4f04-8724-4e25ac07f34f",
   "metadata": {},
   "outputs": [],
   "source": [
    "instruction = pn.pane.Markdown(\"\"\"\n",
    "This dashboard visualizes all global glaciers and allows exploring the relationships\n",
    "between their locations and variables such as their elevation, temperature and annual\n",
    "precipitation.<br><br>Box- or lasso-select on each plot to subselect and hit the \n",
    "\"Clear selection\" button to reset. See the notebook source code for how to build apps\n",
    "like this!\"\"\", width=600)\n",
    "\n",
    "panel_logo = pn.pane.PNG(\n",
    "    'https://panel.holoviz.org/_static/logo_stacked.png',\n",
    "    link_url='https://panel.holoviz.org', height=95, align='center'\n",
    ")\n",
    "\n",
    "oggm_logo = pn.pane.PNG(\n",
    "    'https://raw.githubusercontent.com/OGGM/oggm/master/docs/_static/logos/oggm_s_alpha.png',\n",
    "    link_url='https://oggm.org/', height=100, align='center'\n",
    ")\n",
    "\n",
    "intro = pn.Row(\n",
    "    oggm_logo,\n",
    "    instruction,\n",
    "    pn.layout.HSpacer(),\n",
    "    panel_logo,\n",
    "    sizing_mode='stretch_width'\n",
    ")\n",
    "\n",
    "intro"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "130476bf-0923-46ec-bb39-f349439127e7",
   "metadata": {},
   "source": [
    "### Load and cache data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "361cec45-e131-44f8-8dad-32706e187ded",
   "metadata": {},
   "outputs": [],
   "source": [
    "from holoviews.element.tiles import lon_lat_to_easting_northing\n",
    "\n",
    "@pn.cache\n",
    "def load_data():\n",
    "    df = pd.read_parquet('https://datasets.holoviz.org/oggm_glaciers/v1/oggm_glaciers.parq')\n",
    "    df['latdeg'] = df.cenlat\n",
    "    df['x'], df['y'] = lon_lat_to_easting_northing(df.cenlon, df.cenlat)\n",
    "    return df\n",
    "\n",
    "df = load_data()\n",
    "\n",
    "df.tail()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4d9b4125-eef1-4d28-9557-315f8fb42737",
   "metadata": {},
   "source": [
    "### Set up linked selections"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "336c6b94-062c-4409-b67b-327089616d91",
   "metadata": {},
   "outputs": [],
   "source": [
    "ls = hv.link_selections.instance()\n",
    "\n",
    "def clear_selections(event):\n",
    "    ls.selection_expr = None\n",
    "\n",
    "clear_button = pn.widgets.Button(name='Clear selection', align='center')\n",
    "\n",
    "clear_button.param.watch(clear_selections, 'clicks');\n",
    "\n",
    "total_area = df.area_km2.sum()\n",
    "\n",
    "def count(data):\n",
    "    selected_area  = np.sum(data['area_km2'])\n",
    "    selected_percentage = selected_area / total_area * 100\n",
    "    return f'## Glaciers selected: {len(data)} | Area: {selected_area:.0f} km² ({selected_percentage:.1f}%)</font>'\n",
    "\n",
    "pn.Row(\n",
    "    pn.pane.Markdown(pn.bind(count, ls.selection_param(df)), align='center', width=600),\n",
    "    clear_button\n",
    ").servable(area='header', title='OGGM Glaciers')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a1834f9-5759-448e-86eb-28f92d99d1c6",
   "metadata": {},
   "source": [
    "### Create plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b9b79640-3acf-4722-8038-d192283100a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "geo = df.hvplot.points(\n",
    "    'x', 'y', rasterize=True, tools=['hover'], tiles='ESRI', cmap=bmy, logz=True, colorbar=True,\n",
    "    xaxis=None, yaxis=False, ylim=(-7452837.583633271, 6349198.00989753), min_height=400, responsive=True\n",
    ").opts('Tiles', alpha=0.8)\n",
    "\n",
    "scatter = df.hvplot.scatter(\n",
    "    'avg_prcp', 'mean_elev', rasterize=True, fontscale=1.2, grid=True,\n",
    "    xlabel='Avg. Precipitation', ylabel='Elevation', responsive=True, min_height=400\n",
    ")\n",
    "\n",
    "temp = df.hvplot.hist(\n",
    "    'avg_temp_at_mean_elev', fontscale=1.2, responsive=True, min_height=350, fill_color='#85c1e9'\n",
    ")\n",
    "\n",
    "precipitation = df.hvplot.hist(\n",
    "    'avg_prcp', fontscale=1.2, responsive=True, min_height=350, fill_color='#f1948a'\n",
    ")\n",
    "\n",
    "plots = pn.pane.HoloViews(ls(geo + scatter + temp + precipitation).cols(2).opts(sizing_mode='stretch_both'))\n",
    "plots"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28fc8348-3ef0-4028-ac73-3bcc9e09b46e",
   "metadata": {},
   "source": [
    "## Dashboard content\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "28b00ffa-6ffb-4775-87aa-320710a2b8a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.Column(intro, plots, sizing_mode='stretch_both').servable();"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
