{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas\n",
    "import panel as pn\n",
    "import holoviews as hv\n",
    "\n",
    "from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature\n",
    "\n",
    "pn.extension(sizing_mode=\"stretch_width\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example demonstrates how to put widgets together to build a simple UI for exploring the distribution of sea surface temperatures, as follows:\n",
    "\n",
    "- Declare the various widgets\n",
    "- Declare a function that is decorated with the `pn.depends` to express the dependencies on the widget values\n",
    "- Define a callback that pops up the bandwidth slider to control the kernel density estimate (if it has been enabled)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bins = pn.widgets.IntSlider(name='Number of bins', start=5, end=25, step=5, value=10)\n",
    "kde = pn.widgets.Checkbox(name='Show density estimate')\n",
    "observations = pn.widgets.Checkbox(name='Show individual observations')\n",
    "bandwidth = pn.widgets.FloatSlider(name='KDE Bandwidth', start=0.1, end=1)\n",
    "\n",
    "@pn.depends(bins.param.value, kde.param.value,\n",
    "            observations.param.value, bandwidth.param.value)\n",
    "def get_plot(bins, kde, obs, bw):\n",
    "    plot = sea_surface_temperature.hvplot.hist(bins=bins, normed=True, xlabel='Temperature (C)', padding=0.1, color=\"#A01346\")\n",
    "    if kde:\n",
    "        plot *= sea_surface_temperature.hvplot.kde().opts(bandwidth=bw, color=\"#A01346\")\n",
    "    if obs:\n",
    "        plot *= hv.Spikes(sea_surface_temperature, 'temperature').opts(\n",
    "            line_width=0.1, alpha=0.1, spike_length=0.14, color=\"#A01346\")\n",
    "    return plot\n",
    "\n",
    "widgets = pn.WidgetBox(bins, observations, kde)\n",
    "\n",
    "def add_bandwidth(event):\n",
    "    if event.new:\n",
    "        widgets.append(bandwidth)\n",
    "    else:\n",
    "        widgets.remove(bandwidth)\n",
    "\n",
    "kde.param.watch(add_bandwidth, 'value')\n",
    "\n",
    "pn.Row(widgets, get_plot)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## App\n",
    "\n",
    "Lets wrap it into nice template that can be served via `panel serve temperature_distribution.ipynb`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "description=\"\"\"This example demonstrates how to put widgets together to build a simple UI for exploring the distribution of sea surface temperatures, as follows:\n",
    "\n",
    "- Declare the various widgets\n",
    "- Declare a function that is decorated with the `pn.depends` to express the dependencies on the widget values\n",
    "- Define a callback that pops up the bandwidth slider to control the kernel density estimate (if it has been enabled).\"\"\"\n",
    "pn.template.FastListTemplate(\n",
    "    site=\"Panel\", \n",
    "    title=\"Temperature Distribution\",\n",
    "    sidebar=[widgets],\n",
    "    main=[description, get_plot], main_max_width=\"768px\",\n",
    ").servable();"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
