{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import panel as pn\n",
    "\n",
    "import holoviews as hv\n",
    "import hvplot.pandas # noqa\n",
    "\n",
    "pn.extension(template='fast')\n",
    "\n",
    "pn.state.template.logo = 'https://github.com/allisonhorst/palmerpenguins/raw/main/man/figures/logo.png'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "welcome = \"## Welcome and meet the Palmer penguins!\"\n",
    "\n",
    "penguins_art = pn.pane.PNG('https://raw.githubusercontent.com/allisonhorst/palmerpenguins/main/man/figures/palmerpenguins.png', height=160)\n",
    "\n",
    "credit = \"### Artwork by @allison_horst\"\n",
    "\n",
    "instructions = \"\"\"\n",
    "Use the box-select and lasso-select tools to select a subset of penguins\n",
    "and reveal more information about the selected subgroup through the power\n",
    "of cross-filtering.\n",
    "\"\"\"\n",
    "\n",
    "license = \"\"\"\n",
    "### License\n",
    "\n",
    "Data are available by CC-0 license in accordance with the Palmer Station LTER Data Policy and the LTER Data Access Policy for Type I data.\"\n",
    "\"\"\"\n",
    "\n",
    "art = pn.Column(\n",
    "    welcome, penguins_art, credit, instructions, license,\n",
    "    sizing_mode='stretch_width'\n",
    ").servable(area='sidebar')\n",
    "\n",
    "art"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Building some plots\n",
    "\n",
    "Let us first load the Palmer penguin dataset ([Gorman et al.](https://allisonhorst.github.io/palmerpenguins/)) which contains measurements about a number of penguin species:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "penguins = pd.read_csv('https://datasets.holoviz.org/penguins/v1/penguins.csv')\n",
    "penguins = penguins[~penguins.sex.isnull()].reset_index().sort_values('species')\n",
    "\n",
    "penguins.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we will set up a linked selections instance that will allow us to perform cross-filtering on the plots we will create in the next step:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ls = hv.link_selections.instance()\n",
    "\n",
    "def count(selected):\n",
    "    return f\"## {len(selected)}/{len(penguins)} penguins selected\"\n",
    "\n",
    "selected = pn.pane.Markdown(\n",
    "    pn.bind(count, ls.selection_param(penguins)),\n",
    "    align='center', width=400, margin=(0, 100, 0, 0)\n",
    ")\n",
    "\n",
    "header = pn.Row(\n",
    "    pn.layout.HSpacer(), selected,\n",
    "    sizing_mode='stretch_width'\n",
    ").servable(area='header')\n",
    "\n",
    "selected"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can start plotting the data with hvPlot, which provides a familiar API to pandas `.plot` users but generates interactive plots and use the linked selections object to allow cross-filtering across the plots:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "colors = {\n",
    "    'Adelie': '#1f77b4',\n",
    "    'Gentoo': '#ff7f0e',\n",
    "    'Chinstrap': '#2ca02c'\n",
    "}\n",
    "\n",
    "scatter = penguins.hvplot.points(\n",
    "    'bill_length_mm', 'bill_depth_mm', c='species',\n",
    "    cmap=colors, responsive=True, min_height=300\n",
    ")\n",
    "\n",
    "histogram = penguins.hvplot.hist(\n",
    "    'body_mass_g', by='species', color=hv.dim('species').categorize(colors),\n",
    "    legend=False, alpha=0.5, responsive=True, min_height=300\n",
    ")\n",
    "\n",
    "bars = penguins.hvplot.bar(\n",
    "    'species', 'index', c='species', cmap=colors,\n",
    "    responsive=True, min_height=300, ylabel=''\n",
    ").aggregate(function=np.count_nonzero)\n",
    "\n",
    "violin = penguins.hvplot.violin(\n",
    "    'flipper_length_mm', by=['species', 'sex'], cmap='Category20',\n",
    "    responsive=True, min_height=300, legend='bottom_right'\n",
    ").opts(split='sex')\n",
    "\n",
    "plots = pn.pane.HoloViews(\n",
    "    ls(scatter.opts(show_legend=False) + bars + histogram + violin).opts(sizing_mode='stretch_both').cols(2)\n",
    ").servable(title='Palmer Penguins')\n",
    "\n",
    "plots"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
