{ "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" ] }, { "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 }