From 0e2941fc0babaa1c798a8ad16b9d2c5ea5195b7f Mon Sep 17 00:00:00 2001 From: Isaiah Akorita Date: Mon, 4 Aug 2025 17:14:39 +0100 Subject: [PATCH 1/4] Add how-to section --- doc/how_to/index.md | 10 ++++++++++ doc/index.md | 1 + 2 files changed, 11 insertions(+) create mode 100644 doc/how_to/index.md diff --git a/doc/how_to/index.md b/doc/how_to/index.md new file mode 100644 index 000000000..f1c886fff --- /dev/null +++ b/doc/how_to/index.md @@ -0,0 +1,10 @@ +# How-To Guides + +How-to guides are practical, problem-oriented instructions that help you accomplish specific tasks with hvPlot. These guides assume you're already familiar with the basics and want to solve particular problems or achieve specific goals. + +```{toctree} +:titlesonly: +:hidden: +:maxdepth: 2 + +``` diff --git a/doc/index.md b/doc/index.md index e868f5cec..c1fbf0941 100644 --- a/doc/index.md +++ b/doc/index.md @@ -434,6 +434,7 @@ align: center Tutorials User Guide +How-To Guides Gallery Reference Developer Guide From 4c3aca0818cd94bfa4a54c15cb869e938f9d7368 Mon Sep 17 00:00:00 2001 From: Isaiah Akorita Date: Tue, 5 Aug 2025 15:08:33 +0100 Subject: [PATCH 2/4] split Widgets user guide into 3 --- doc/explanation/grouping_options.ipynb | 386 ++++++++++++++++++ doc/explanation/index.md | 11 + doc/how_to/explore_with_widgets.ipynb | 188 +++++++++ doc/how_to/index.md | 1 + doc/index.md | 1 + doc/ref/api_compatibility/index.md | 1 + doc/ref/api_compatibility/panel_widgets.ipynb | 146 +++++++ 7 files changed, 734 insertions(+) create mode 100644 doc/explanation/grouping_options.ipynb create mode 100644 doc/explanation/index.md create mode 100644 doc/how_to/explore_with_widgets.ipynb create mode 100644 doc/ref/api_compatibility/panel_widgets.ipynb diff --git a/doc/explanation/grouping_options.ipynb b/doc/explanation/grouping_options.ipynb new file mode 100644 index 000000000..37793ebc9 --- /dev/null +++ b/doc/explanation/grouping_options.ipynb @@ -0,0 +1,386 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "02909b6b", + "metadata": {}, + "source": [ + "# Understanding Grouping and Coloring Options\n", + "\n", + "This guide explains the key differences between hvPlot's three main approaches to handling categorical data: `groupby`, `by`, and `color`/`c`. Understanding these differences is important for creating effective visualizations and choosing the right approach for your specific use case." + ] + }, + { + "cell_type": "markdown", + "id": "817592aa", + "metadata": {}, + "source": [ + "## Overview of the Three Approaches\n", + "\n", + "hvPlot provides three primary ways to handle categorical data in your plots:\n", + "\n", + "1. **`groupby`**: Creates interactive widgets with [HoloMap](inv:holoviews#holoviews.HoloMap) / [DynamicMap](inv:holoviews#holoviews.DynamicMap) containers\n", + "2. **`by`**: Creates multiple plot elements in [NdOverlay](inv:holoviews#holoviews.NdOverlay) or [NdLayout](inv:holoviews#holoviews.NdLayout) containers\n", + "3. **`color`/`c`**: Creates vectorized coloring within a single plot element\n", + "\n", + "Each approach produces different outputs, offers different interaction capabilities, and has different performance characteristics." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dbeabe0c", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.pandas\n", + "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()\n", + "penguins.head(3)" + ] + }, + { + "cell_type": "markdown", + "id": "98a0b527", + "metadata": {}, + "source": [ + "## `groupby`: Interactive Widgets\n", + "\n", + "The `groupby` parameter creates **interactive widgets** that allow users to filter and explore different subsets of your data dynamically.\n", + "\n", + "### What it creates:\n", + "- **HoloViews containers**: [HoloMap](inv:holoviews#holoviews.HoloMap) or [DynamicMap](inv:holoviews#holoviews.DynamicMap) object\n", + "- **Interactive widgets**: Automatically generated based on data type\n", + "- **Single view at a time**: Only one category visible per interaction\n", + "\n", + "### When to use:\n", + "- When you want to explore different subsets of data interactively\n", + "- When you have many categories that would clutter a single plot\n", + "- When building dashboards or interactive reports\n", + "- When you need to reduce visual complexity" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2005058", + "metadata": {}, + "outputs": [], + "source": [ + "plot_groupby = penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " groupby='species',\n", + " title=\"Groupby: Interactive Widget\",\n", + " width=400,\n", + ")\n", + "plot_groupby" + ] + }, + { + "cell_type": "markdown", + "id": "ae7b6cd5", + "metadata": {}, + "source": [ + "### Indexing and access:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "55e5fd82", + "metadata": {}, + "outputs": [], + "source": [ + "# Access specific category: plot['category_value']\n", + "adelie_only = plot_groupby['Adelie'] # Shows only Adelie penguins\n", + "print(f\"Type of groupby plot: {type(plot_groupby)}\")\n", + "print(f\"Type of specific species: {type(adelie_only)}\")\n", + "adelie_only" + ] + }, + { + "cell_type": "markdown", + "id": "30b3be0e", + "metadata": {}, + "source": [ + "## `by`: Multiple Plot Elements\n", + "\n", + "The `by` parameter creates **multiple plot elements** shown simultaneously, either overlaid or in separate subplots.\n", + "\n", + "### What it creates:\n", + "- [NdOverlay](inv:holoviews#holoviews.NdOverlay): Multiple elements overlaid (default)\n", + "- [NdLayout](inv:holoviews#holoviews.NdLayout): Separate subplots when `subplots=True`\n", + "- **All categories visible**: Simultaneously displayed\n", + "\n", + "### When to use:\n", + "- When you want to compare categories side-by-side\n", + "- When you have a manageable number of categories (typically < 10)\n", + "- When color differentiation is sufficient for your analysis\n", + "- When you need all data visible at once" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44a01c85", + "metadata": {}, + "outputs": [], + "source": [ + "overlay_plot = penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " by='species',\n", + " title=\"By: Overlaid Elements\"\n", + ")\n", + "overlay_plot" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d18719e", + "metadata": {}, + "outputs": [], + "source": [ + "plot_by_subplots = penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " by='species',\n", + " width=300,\n", + " subplots=True,\n", + ")\n", + "plot_by_subplots.cols(2)" + ] + }, + { + "cell_type": "markdown", + "id": "429174c7", + "metadata": {}, + "source": [ + "### Indexing and access:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d21ed90c", + "metadata": {}, + "outputs": [], + "source": [ + "# Access specific category: plot['category_value']\n", + "adelie_element = overlay_plot['Adelie'] # Returns just the element for Adelie penguins\n", + "print(f\"Type of 'by' plot: {type(overlay_plot)}\")\n", + "print(f\"Type of specific species element: {type(adelie_element)}\")\n", + "adelie_element" + ] + }, + { + "cell_type": "markdown", + "id": "3fe7048d", + "metadata": {}, + "source": [ + "## `color`/`c`: Vectorized Coloring\n", + "\n", + "The `color` parameter creates **vectorized coloring** within a single plot element, where each data point is colored based on the category value.\n", + "\n", + "### What it creates:\n", + "- **Single plot element**: One unified [Scatter](inv:holoviews#holoviews.Scatter), [Curve](inv:holoviews#holoviews.Curve), etc.\n", + "- **Vectorized coloring**: Each point colored by category\n", + "- **Cannot be indexed**: Single element, not separable by category\n", + "\n", + "### When to use:\n", + "- When you want the best performance for large datasets\n", + "- When you need smooth, continuous color mapping\n", + "- When you don't need to isolate specific categories" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f54ccbed", + "metadata": {}, + "outputs": [], + "source": [ + "plot_color = penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " color='species',\n", + " title=\"Color: Vectorized Coloring\"\n", + ")\n", + "plot_color" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4fb28a9", + "metadata": {}, + "outputs": [], + "source": [ + "# Alternative syntax using 'c'\n", + "plot_c = penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " c='species',\n", + " title=\"Using 'c' parameter (same result)\"\n", + ")\n", + "plot_c" + ] + }, + { + "cell_type": "markdown", + "id": "60b4c757", + "metadata": {}, + "source": [ + "### Indexing and access:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab54c88e", + "metadata": {}, + "outputs": [], + "source": [ + "# Cannot index by category - this won't work:\n", + "print(f\"Type of 'color' plot: {type(plot_color)}\")\n", + "try:\n", + " adelie_color = plot_color['Adelie'] # This will raise an error!\n", + "except Exception:\n", + " print(\"Error: You cannot index a single element by category!\")" + ] + }, + { + "cell_type": "markdown", + "id": "1626f2c0", + "metadata": {}, + "source": [ + "## Visual Output Comparison\n", + "\n", + "Let's compare all three approaches side by side to see the differences:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1545149", + "metadata": {}, + "outputs": [], + "source": [ + "import panel as pn\n", + "\n", + "width = 300\n", + "\n", + "groupby_plot = penguins.hvplot.scatter(\n", + " x='bill_length_mm', y='bill_depth_mm',\n", + " groupby='species', title=\"groupby='species'\",\n", + " frame_width=width, widget_location='bottom_right',\n", + ")\n", + "\n", + "by_plot = penguins.hvplot.scatter(\n", + " x='bill_length_mm', y='bill_depth_mm',\n", + " by='species', title=\"by='species'\",\n", + " frame_width=width,\n", + ")\n", + "\n", + "color_plot = penguins.hvplot.scatter(\n", + " x='bill_length_mm', y='bill_depth_mm',\n", + " color='species', title=\"color='species'\",\n", + " frame_width=width,\n", + ")\n", + "\n", + "pn.Column(pn.Row(by_plot, color_plot), groupby_plot)" + ] + }, + { + "cell_type": "markdown", + "id": "bdcbe3e1", + "metadata": {}, + "source": [ + "### Key Visual Differences:\n", + "\n", + "- **`groupby='species'`** shows only one species at a time with a widget\n", + "- **`by='species'`** shows all species overlaid with different colors and a legend\n", + "- **`color='species'`** looks similar to `by` but is a single plot element\n", + "\n", + "When using `subplots=True` with `by`, you get separate panels:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b777d41", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='bill_length_mm', y='bill_depth_mm',\n", + " by='species', subplots=True,\n", + " width=300, height=250,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "0658c3a1", + "metadata": {}, + "source": [ + "## Advanced: Combining Approaches\n", + "\n", + "You can combine these approaches for more complex visualizations:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "754427cf", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='bill_length_mm', y='bill_depth_mm',\n", + " groupby='island', color='species',\n", + " width=500, height=400,\n", + " title=\"Groupby island, colored by species\"\n", + ")\n" + ] + }, + { + "cell_type": "markdown", + "id": "05067653", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "| Aspect | `groupby` | `by` | `color`/`c` |\n", + "| ----------------- | ------------------ | ------------------ | ---------------------- |\n", + "| **Holoviews Object** | [HoloMap](inv:holoviews#holoviews.HoloMap) / [DynamicMap](inv:holoviews#holoviews.DynamicMap) | [NdOverlay](inv:holoviews#holoviews.NdLayout) / [NdLayout](inv:holoviews#holoviews.NdLayout) | Single Element |\n", + "| **Interactivity** | Widget-based | Static overlay | Static single plot |\n", + "| **Indexing** | `plot['category']` | `plot['category']` | Not available |\n", + "| **Performance** | Variable | Medium | Best |\n", + "| **Visual** | One at a time | All simultaneous | All simultaneous |\n", + "| **Use case** | Exploration | Comparison | Performance/Aesthetics |\n", + "\n", + "### Choose the approach that best matches your needs:\n", + "\n", + "- **Use `groupby`** for interactive exploration of many categories\n", + "- **Use `by`** for direct comparison of manageable categories \n", + "- **Use `color`** for performance with large datasets or aesthetic coloring\n", + "\n", + ":::{admonition} Further Reading\n", + ":class: seealso\n", + "See the [HoloViews Reference Manual](https://holoviews.org/reference_manual/index.html) for more information on the various objects created by a hvPlot plot.\n", + ":::" + ] + } + ], + "metadata": { + "language_info": { + "name": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/explanation/index.md b/doc/explanation/index.md new file mode 100644 index 000000000..aebb9464f --- /dev/null +++ b/doc/explanation/index.md @@ -0,0 +1,11 @@ +# Explanation + +Explanation guides provide in-depth understanding of key concepts in hvPlot. These guides help you understand the reasoning behind design decisions and when to use different approaches. + +```{toctree} +:titlesonly: +:hidden: +:maxdepth: 2 + +grouping_options +``` diff --git a/doc/how_to/explore_with_widgets.ipynb b/doc/how_to/explore_with_widgets.ipynb new file mode 100644 index 000000000..3760b6007 --- /dev/null +++ b/doc/how_to/explore_with_widgets.ipynb @@ -0,0 +1,188 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "770e0358", + "metadata": {}, + "source": [ + "# How to Explore Multidimensional Datasets with Widgets\n", + "\n", + "This guide shows you how to use hvPlot's automatic widget creation to interactively explore datasets with multiple dimensions. When you use the `groupby` parameter, hvPlot automatically creates widgets that let you filter and explore your data dynamically." + ] + }, + { + "cell_type": "markdown", + "id": "a30afa69", + "metadata": {}, + "source": [ + ":::{note}\n", + " When viewing on a static website, the widgets will be inoperable. To explore this functionality fully, download the notebook and run it in a live python environment.\n", + ":::" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f241bf4d", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.pandas # noqa\n", + "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()" + ] + }, + { + "cell_type": "markdown", + "id": "a1a16b3c", + "metadata": {}, + "source": [ + "## Basic Widget Creation with groupby\n", + "\n", + "When you use `groupby`, hvPlot automatically selects the appropriate widget type based on your data. For categorical data like the 'species' column (composed of strings), hvPlot creates a Select widget." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ee6a096e", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " groupby='species',\n", + " width=400\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "ab1368b8", + "metadata": {}, + "source": [ + "## Customizing Widget Placement\n", + "\n", + "You can control where the widget appears using the `widget_location` option. This is useful for creating layouts that work better with your specific visualization needs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "86fe3e21", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " groupby='species',\n", + " widget_location='top_left'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "19ed72ac", + "metadata": {}, + "source": [ + "## Changing Widget Types\n", + "\n", + "You can customize which widget class to use through the `widgets` parameter. For example, you might prefer a slider instead of a dropdown selector for better user experience." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc423294", + "metadata": {}, + "outputs": [], + "source": [ + "import panel as pn\n", + "\n", + "penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " groupby='species',\n", + " widgets={'species': pn.widgets.DiscreteSlider},\n", + " widget_location='top_left',\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "3300b323", + "metadata": {}, + "source": [ + "## Exploring Multiple Dimensions\n", + "\n", + "The penguins dataset has several categorical dimensions you can explore. Try grouping by different variables to discover patterns in the data:\n", + "\n", + "### Group by Island" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "530888e6", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='flipper_length_mm',\n", + " y='body_mass_g',\n", + " groupby='island',\n", + " width=400,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "4c2b848c", + "metadata": {}, + "source": [ + "### Group by Sex\n", + "\n", + "You can also explore differences between male and female penguins:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35bbf39a", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='flipper_length_mm',\n", + " groupby='sex',\n", + " color='species',\n", + " width=400,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "462915a5-3a79-4792-811c-f4df6eb59825", + "metadata": {}, + "source": [ + ":::{admonition} Next Steps\n", + ":class: seealso\n", + "\n", + "- For more advanced widget customization using Panel, see the [Panel Widgets Reference](../ref/api_compatibility/panel_widgets.ipynb)\n", + "- To understand the differences between `groupby`, `by`, and `color` parameters, see the [Grouping and Coloring Options Explanation](../explanation/grouping_options.ipynb)\n", + ":::" + ] + } + ], + "metadata": { + "language_info": { + "name": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/how_to/index.md b/doc/how_to/index.md index f1c886fff..2813fb273 100644 --- a/doc/how_to/index.md +++ b/doc/how_to/index.md @@ -7,4 +7,5 @@ How-to guides are practical, problem-oriented instructions that help you accompl :hidden: :maxdepth: 2 +Explore Multidimensional datasets ``` diff --git a/doc/index.md b/doc/index.md index c1fbf0941..5340961fd 100644 --- a/doc/index.md +++ b/doc/index.md @@ -437,6 +437,7 @@ User Guide How-To Guides Gallery Reference +Explanation Developer Guide Releases Roadmap diff --git a/doc/ref/api_compatibility/index.md b/doc/ref/api_compatibility/index.md index b4e5636a4..de6992718 100644 --- a/doc/ref/api_compatibility/index.md +++ b/doc/ref/api_compatibility/index.md @@ -7,4 +7,5 @@ This section aims to provide more precise information about the compatibility of :maxdepth: 2 Pandas +Panel Widgets ``` diff --git a/doc/ref/api_compatibility/panel_widgets.ipynb b/doc/ref/api_compatibility/panel_widgets.ipynb new file mode 100644 index 000000000..bec081d03 --- /dev/null +++ b/doc/ref/api_compatibility/panel_widgets.ipynb @@ -0,0 +1,146 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "16cbd331", + "metadata": {}, + "source": [ + "# Panel Widgets\n", + "\n", + "This reference shows advanced widget functionality using Panel for fine-grained control over hvPlot interactivity. Panel provides extensive customization options beyond hvPlot's built-in widget support." + ] + }, + { + "cell_type": "markdown", + "id": "06bb92b5", + "metadata": {}, + "source": [ + ":::{warning}\n", + "This functionality requires Panel to be installed. The API shown here may change in future versions.\n", + ":::\n", + ":::{note}\n", + " When viewing on a static website, the widgets will be inoperable. To explore this functionality fully, download the notebook and run it in a live python environment.\n", + ":::" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2830d9e5", + "metadata": {}, + "outputs": [], + "source": [ + "import panel as pn\n", + "import hvplot.pandas # noqa\n", + "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()" + ] + }, + { + "cell_type": "markdown", + "id": "945104bd", + "metadata": {}, + "source": [ + "## Using Widgets as Plot Arguments\n", + "\n", + "Panel widgets can be used directly as arguments to hvPlot methods, allowing users to interactively select plot parameters like axes and plot types." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fbda9b9e", + "metadata": {}, + "outputs": [], + "source": [ + "x = pn.widgets.Select(name='x', options=['bill_length_mm', 'bill_depth_mm'])\n", + "y = pn.widgets.Select(name='y', options=['flipper_length_mm', 'body_mass_g'])\n", + "kind = pn.widgets.Select(name='kind', value='scatter', options=['scatter', 'bivariate'])\n", + "\n", + "plot = penguins.hvplot(x=x, y=y, kind=kind, colorbar=False, width=600)\n", + "pn.Row(pn.WidgetBox(x, y, kind), plot)" + ] + }, + { + "cell_type": "markdown", + "id": "2534030a", + "metadata": {}, + "source": [ + "## Using Functions with `pn.depends`\n", + "\n", + "For more complex interactions, you can create functions decorated with `pn.depends` that respond to widget changes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "990e3783", + "metadata": {}, + "outputs": [], + "source": [ + "x = pn.widgets.Select(name='x', options=['bill_length_mm', 'bill_depth_mm'])\n", + "y = pn.widgets.Select(name='y', options=['flipper_length_mm', 'body_mass_g'])\n", + "kind = pn.widgets.Select(name='kind', value='scatter', options=['scatter', 'bivariate'])\n", + "by_species = pn.widgets.Checkbox(name='By species')\n", + "color = pn.widgets.ColorPicker(value='#ff0000')\n", + "\n", + "@pn.depends(by_species, color)\n", + "def by_species_fn(by_species, color):\n", + " return 'species' if by_species else color\n", + "\n", + "plot = penguins.hvplot(x=x, y=y, kind=kind, c=by_species_fn, colorbar=False, width=400, legend='top_right')\n", + "\n", + "pn.Row(pn.WidgetBox(x, y, kind, color, by_species), plot)" + ] + }, + { + "cell_type": "markdown", + "id": "db5027d9", + "metadata": {}, + "source": [ + "## Widget Callbacks and Interactions\n", + "\n", + "You can also add callbacks to create more sophisticated widget interactions, such as enabling/disabling widgets based on other widget values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9535677a", + "metadata": {}, + "outputs": [], + "source": [ + "def update(event):\n", + " if kind.value == 'bivariate':\n", + " color.disabled = True\n", + " by_species.disabled = True\n", + " else:\n", + " color.disabled = False\n", + " by_species.disabled = False\n", + "\n", + "kind.param.watch(update, 'value');" + ] + }, + { + "cell_type": "markdown", + "id": "28cd0a30", + "metadata": {}, + "source": [ + ":::{admonition} Additional Resources\n", + ":class: seealso\n", + "- [Panel HoloViews Pane Documentation](https://panel.pyviz.org/reference/panes/HoloViews.html)\n", + "- [Panel Widgets Reference Gallery](https://panel.pyviz.org/reference/index.html)\n", + "- [Panel API Documentation](https://panel.pyviz.org/api/)\n", + ":::" + ] + } + ], + "metadata": { + "language_info": { + "name": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From f906781a553aa7953d337ed3537263d797a0eed3 Mon Sep 17 00:00:00 2001 From: Isaiah Akorita Date: Tue, 5 Aug 2025 16:16:38 +0100 Subject: [PATCH 3/4] fix typo --- doc/explanation/grouping_options.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/explanation/grouping_options.ipynb b/doc/explanation/grouping_options.ipynb index 37793ebc9..ae83f5d17 100644 --- a/doc/explanation/grouping_options.ipynb +++ b/doc/explanation/grouping_options.ipynb @@ -355,7 +355,7 @@ "\n", "| Aspect | `groupby` | `by` | `color`/`c` |\n", "| ----------------- | ------------------ | ------------------ | ---------------------- |\n", - "| **Holoviews Object** | [HoloMap](inv:holoviews#holoviews.HoloMap) / [DynamicMap](inv:holoviews#holoviews.DynamicMap) | [NdOverlay](inv:holoviews#holoviews.NdLayout) / [NdLayout](inv:holoviews#holoviews.NdLayout) | Single Element |\n", + "| **Holoviews Object** | [HoloMap](inv:holoviews#holoviews.HoloMap) / [DynamicMap](inv:holoviews#holoviews.DynamicMap) | [NdOverlay](inv:holoviews#holoviews.NdOverlay) / [NdLayout](inv:holoviews#holoviews.NdLayout) | Single Element |\n", "| **Interactivity** | Widget-based | Static overlay | Static single plot |\n", "| **Indexing** | `plot['category']` | `plot['category']` | Not available |\n", "| **Performance** | Variable | Medium | Best |\n", From 696b4e3d685873b81db4ed735d0f8ec678733697 Mon Sep 17 00:00:00 2001 From: Isaiah Akorita Date: Thu, 28 Aug 2025 22:54:25 +0100 Subject: [PATCH 4/4] review --- doc/explanation/grouping_options.ipynb | 106 ++++++++++++------ doc/how_to/explore_with_widgets.ipynb | 92 ++++++--------- doc/ref/api_compatibility/panel_widgets.ipynb | 2 +- doc/ref/plotting_options/data.ipynb | 2 +- 4 files changed, 111 insertions(+), 91 deletions(-) diff --git a/doc/explanation/grouping_options.ipynb b/doc/explanation/grouping_options.ipynb index ae83f5d17..c39bb3eec 100644 --- a/doc/explanation/grouping_options.ipynb +++ b/doc/explanation/grouping_options.ipynb @@ -7,7 +7,7 @@ "source": [ "# Understanding Grouping and Coloring Options\n", "\n", - "This guide explains the key differences between hvPlot's three main approaches to handling categorical data: `groupby`, `by`, and `color`/`c`. Understanding these differences is important for creating effective visualizations and choosing the right approach for your specific use case." + "This guide explains the key differences between hvPlot's three main approaches to handling categorical data: [groupby](option-groupby), [by](option-by), and [color/c](option-color). Understanding these differences is important for creating effective visualizations and choosing the right approach for your specific use case." ] }, { @@ -19,8 +19,8 @@ "\n", "hvPlot provides three primary ways to handle categorical data in your plots:\n", "\n", - "1. **`groupby`**: Creates interactive widgets with [HoloMap](inv:holoviews#holoviews.HoloMap) / [DynamicMap](inv:holoviews#holoviews.DynamicMap) containers\n", - "2. **`by`**: Creates multiple plot elements in [NdOverlay](inv:holoviews#holoviews.NdOverlay) or [NdLayout](inv:holoviews#holoviews.NdLayout) containers\n", + "1. **`groupby`**: Creates interactive widgets with [HoloMap](https://holoviews.org/reference_manual/holoviews.html#holoviews.HoloMap) / [DynamicMap](https://holoviews.org/reference_manual/holoviews.html#holoviews.DynamicMap) containers\n", + "2. **`by`**: Creates multiple plot elements in [NdOverlay](https://holoviews.org/reference_manual/holoviews.html#holoviews.NdOverlay) or [NdLayout](https://holoviews.org/reference_manual/holoviews.html#holoviews.NdLayout) containers\n", "3. **`color`/`c`**: Creates vectorized coloring within a single plot element\n", "\n", "Each approach produces different outputs, offers different interaction capabilities, and has different performance characteristics." @@ -49,7 +49,7 @@ "The `groupby` parameter creates **interactive widgets** that allow users to filter and explore different subsets of your data dynamically.\n", "\n", "### What it creates:\n", - "- **HoloViews containers**: [HoloMap](inv:holoviews#holoviews.HoloMap) or [DynamicMap](inv:holoviews#holoviews.DynamicMap) object\n", + "- **HoloViews containers**: [HoloMap](https://holoviews.org/reference_manual/holoviews.html#holoviews.HoloMap) or [DynamicMap](https://holoviews.org/reference_manual/holoviews.html#holoviews.DynamicMap) object\n", "- **Interactive widgets**: Automatically generated based on data type\n", "- **Single view at a time**: Only one category visible per interaction\n", "\n", @@ -73,6 +73,7 @@ " groupby='species',\n", " title=\"Groupby: Interactive Widget\",\n", " width=400,\n", + " dynamic=False, # loads all the data on the frontend to enable interactivity on the fly\n", ")\n", "plot_groupby" ] @@ -82,7 +83,18 @@ "id": "ae7b6cd5", "metadata": {}, "source": [ - "### Indexing and access:" + "### Indexing and Access\n", + "\n", + "When you use `groupby`, hvPlot creates a **HoloViews container object** (HoloMap or DynamicMap) that acts like a dictionary. This container stores separate plot elements for each category value, which is why you can \"index into\" specific categories.\n", + "\n", + "**Why indexing works**: The container maps category values (like `'Adelie'`, `'Chinstrap'`, `'Gentoo'`) to individual plot elements. Each category becomes a \"key\" that you can use to access its corresponding plot.\n", + "\n", + "**What happens when you index**: You extract a single plot element from the container, giving you just the data for that specific category without the interactive widget.\n", + "\n", + "**Use cases**: \n", + "- Extract specific categories for further analysis\n", + "- Combine individual categories in custom layouts\n", + "- Access the underlying plot element for advanced customization" ] }, { @@ -109,8 +121,8 @@ "The `by` parameter creates **multiple plot elements** shown simultaneously, either overlaid or in separate subplots.\n", "\n", "### What it creates:\n", - "- [NdOverlay](inv:holoviews#holoviews.NdOverlay): Multiple elements overlaid (default)\n", - "- [NdLayout](inv:holoviews#holoviews.NdLayout): Separate subplots when `subplots=True`\n", + "- [NdOverlay](https://holoviews.org/reference_manual/holoviews.html#holoviews.NdOverlay): Multiple elements overlaid (default)\n", + "- [NdLayout](https://holoviews.org/reference_manual/holoviews.html#holoviews.NdLayout): Separate subplots when `subplots=True`\n", "- **All categories visible**: Simultaneously displayed\n", "\n", "### When to use:\n", @@ -158,7 +170,15 @@ "id": "429174c7", "metadata": {}, "source": [ - "### Indexing and access:" + "### Indexing and Access\n", + "\n", + "Similar to `groupby`, using `by` creates a **HoloViews container object** (NdOverlay or NdLayout) that you can index into. However, the behavior is different because all elements are displayed simultaneously.\n", + "\n", + "**Why indexing works**: The NdOverlay/NdLayout container stores individual plot elements for each category, just like a dictionary mapping category values to plot elements.\n", + "\n", + "**What happens when you index**: You extract a single plot element from the overlay/layout. This gives you just that category's data as a standalone plot element, separate from the others.\n", + "\n", + "**Key difference from groupby**: While `groupby` shows one category at a time with widgets, `by` shows all categories together, but you can still extract individual in the same way as `groupby` objects." ] }, { @@ -185,7 +205,7 @@ "The `color` parameter creates **vectorized coloring** within a single plot element, where each data point is colored based on the category value.\n", "\n", "### What it creates:\n", - "- **Single plot element**: One unified [Scatter](inv:holoviews#holoviews.Scatter), [Curve](inv:holoviews#holoviews.Curve), etc.\n", + "- **Single plot element**: One unified [Scatter](https://holoviews.org/reference_manual/holoviews.html#holoviews.Scatter), [Curve](https://holoviews.org/reference_manual/holoviews.html#holoviews.Curve), etc.\n", "- **Vectorized coloring**: Each point colored by category\n", "- **Cannot be indexed**: Single element, not separable by category\n", "\n", @@ -211,29 +231,24 @@ "plot_color" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "d4fb28a9", - "metadata": {}, - "outputs": [], - "source": [ - "# Alternative syntax using 'c'\n", - "plot_c = penguins.hvplot.scatter(\n", - " x='bill_length_mm',\n", - " y='bill_depth_mm',\n", - " c='species',\n", - " title=\"Using 'c' parameter (same result)\"\n", - ")\n", - "plot_c" - ] - }, { "cell_type": "markdown", "id": "60b4c757", "metadata": {}, "source": [ - "### Indexing and access:" + "### Indexing and Access\n", + "\n", + "Unlike `groupby` and `by`, using `color` creates a **single plot element** rather than a container object. This means indexing by category is not possible.\n", + "\n", + "**Why indexing doesn't work**: There's no container structure - just one plot element where the color information is stored as data within the element itself. The categories exist as color mappings, not as separate, accessible plot elements.\n", + "\n", + "**What this means**: All your data points are part of one unified plot object. The categorical information is encoded in the visual properties (colors) rather than the data structure.\n", + "\n", + "**Implications**:\n", + "- You cannot programmatically separate categories\n", + "- Better performance since there's only one plot element to render\n", + "- All data is always visible\n", + "- Ideal when you want aesthetic grouping without interactive separation" ] }, { @@ -243,14 +258,40 @@ "metadata": {}, "outputs": [], "source": [ - "# Cannot index by category - this won't work:\n", "print(f\"Type of 'color' plot: {type(plot_color)}\")\n", "try:\n", - " adelie_color = plot_color['Adelie'] # This will raise an error!\n", + " adelie_color = plot_color['Adelie'] # This will raise an error.\n", "except Exception:\n", " print(\"Error: You cannot index a single element by category!\")" ] }, + { + "cell_type": "markdown", + "id": "dc4f9890", + "metadata": {}, + "source": [ + "## Understanding Container Objects vs Single Elements\n", + "\n", + "The key concept underlying these differences is **how HoloViews organizes your data**:\n", + "\n", + "### Container Objects (indexable)\n", + "- **`groupby`** → HoloMap/DynamicMap: `{category: plot_element}`\n", + "- **`by`** → NdOverlay/NdLayout: `{category: plot_element}`\n", + "\n", + "These containers act like dictionaries where each category value maps to a separate plot element. This structure enables indexing with `plot['category_name']`.\n", + "\n", + "### Single Elements (not indexable) \n", + "- **`color`** → Single plot element (Scatter, Curve, etc.)\n", + "\n", + "Here, all data points belong to one plot element. Categories are encoded as visual properties (colors) rather than separate data structures.\n", + "\n", + "This fundamental difference affects not just indexing, but also performance, interactivity, and how you can manipulate the resulting plots.\n", + "\n", + ":::{seealso}\n", + "[Introduction to HoloViews Elements](https://holoviews.org/getting_started/Introduction.html)\n", + ":::" + ] + }, { "cell_type": "markdown", "id": "1626f2c0", @@ -276,6 +317,7 @@ " x='bill_length_mm', y='bill_depth_mm',\n", " groupby='species', title=\"groupby='species'\",\n", " frame_width=width, widget_location='bottom_right',\n", + " shared_axes=False,\n", ")\n", "\n", "by_plot = penguins.hvplot.scatter(\n", @@ -290,7 +332,7 @@ " frame_width=width,\n", ")\n", "\n", - "pn.Column(pn.Row(by_plot, color_plot), groupby_plot)" + "pn.Column(pn.Row(groupby_plot, by_plot), color_plot)" ] }, { @@ -341,7 +383,7 @@ "penguins.hvplot.scatter(\n", " x='bill_length_mm', y='bill_depth_mm',\n", " groupby='island', color='species',\n", - " width=500, height=400,\n", + " width=500, height=400, dynamic=False,\n", " title=\"Groupby island, colored by species\"\n", ")\n" ] @@ -355,7 +397,7 @@ "\n", "| Aspect | `groupby` | `by` | `color`/`c` |\n", "| ----------------- | ------------------ | ------------------ | ---------------------- |\n", - "| **Holoviews Object** | [HoloMap](inv:holoviews#holoviews.HoloMap) / [DynamicMap](inv:holoviews#holoviews.DynamicMap) | [NdOverlay](inv:holoviews#holoviews.NdOverlay) / [NdLayout](inv:holoviews#holoviews.NdLayout) | Single Element |\n", + "| **Holoviews Object** | [HoloMap](https://holoviews.org/reference_manual/holoviews.html#holoviews.HoloMap) / [DynamicMap](https://holoviews.org/reference_manual/holoviews.html#holoviews.DynamicMap) | [NdOverlay](https://holoviews.org/reference_manual/holoviews.html#holoviews.NdOverlay) / [NdLayout](https://holoviews.org/reference_manual/holoviews.html#holoviews.NdLayout) | Single Element |\n", "| **Interactivity** | Widget-based | Static overlay | Static single plot |\n", "| **Indexing** | `plot['category']` | `plot['category']` | Not available |\n", "| **Performance** | Variable | Medium | Best |\n", diff --git a/doc/how_to/explore_with_widgets.ipynb b/doc/how_to/explore_with_widgets.ipynb index 3760b6007..d224ba2c3 100644 --- a/doc/how_to/explore_with_widgets.ipynb +++ b/doc/how_to/explore_with_widgets.ipynb @@ -7,7 +7,7 @@ "source": [ "# How to Explore Multidimensional Datasets with Widgets\n", "\n", - "This guide shows you how to use hvPlot's automatic widget creation to interactively explore datasets with multiple dimensions. When you use the `groupby` parameter, hvPlot automatically creates widgets that let you filter and explore your data dynamically." + "This guide shows you how to use hvPlot's automatic widget creation to interactively explore datasets with multiple dimensions. When you use the `groupby` parameter, hvPlot automatically creates widgets that let you drill-down into and explore your data dynamically." ] }, { @@ -16,22 +16,10 @@ "metadata": {}, "source": [ ":::{note}\n", - " When viewing on a static website, the widgets will be inoperable. To explore this functionality fully, download the notebook and run it in a live python environment.\n", + "When viewing on a static website, the widgets will be inoperable. To explore this functionality fully, download the notebook and run it in a live python environment.\n", ":::" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "f241bf4d", - "metadata": {}, - "outputs": [], - "source": [ - "import hvplot.pandas # noqa\n", - "\n", - "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()" - ] - }, { "cell_type": "markdown", "id": "a1a16b3c", @@ -39,7 +27,7 @@ "source": [ "## Basic Widget Creation with groupby\n", "\n", - "When you use `groupby`, hvPlot automatically selects the appropriate widget type based on your data. For categorical data like the 'species' column (composed of strings), hvPlot creates a Select widget." + "When you use [`groupby`](option-groupby), hvPlot automatically selects the appropriate widget type based on your data. For categorical data like the 'species' column (composed of strings), hvPlot creates a drop-down menu (from a [Panel Select widget](https://panel.holoviz.org/reference/widgets/Select.html))." ] }, { @@ -49,6 +37,9 @@ "metadata": {}, "outputs": [], "source": [ + "import hvplot.pandas # noqa\n", + "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()\n", "penguins.hvplot.scatter(\n", " x='bill_length_mm',\n", " y='bill_depth_mm',\n", @@ -59,54 +50,64 @@ }, { "cell_type": "markdown", - "id": "ab1368b8", + "id": "ee650c0d", "metadata": {}, "source": [ - "## Customizing Widget Placement\n", + "### Widget Types for Different Data Types\n", + "\n", + "hvPlot automatically chooses the appropriate widget type based on your data:\n", + "\n", + "- **Categorical/String data** → Drop-down Select widget (as shown above)\n", + "- **Numerical data** → [IntSlider widget](https://panel.holoviz.org/reference/widgets/IntSlider.html) for continuous exploration\n", + "- **Datetime data** → [DatetimeSlider widget](https://panel.holoviz.org/reference/widgets/DatetimeSlider.html) for temporal exploration\n", "\n", - "You can control where the widget appears using the `widget_location` option. This is useful for creating layouts that work better with your specific visualization needs." + "For numerical columns like `year`, hvPlot creates a slider widget that lets you explore different values from the different years." ] }, { "cell_type": "code", "execution_count": null, - "id": "86fe3e21", + "id": "495f9a91", "metadata": {}, "outputs": [], "source": [ + "import hvplot.pandas # noqa\n", + "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()\n", "penguins.hvplot.scatter(\n", " x='bill_length_mm',\n", " y='bill_depth_mm',\n", - " groupby='species',\n", - " widget_location='top_left'\n", + " groupby='year',\n", + " color='species',\n", + " width=400\n", ")" ] }, { "cell_type": "markdown", - "id": "19ed72ac", + "id": "ab1368b8", "metadata": {}, "source": [ - "## Changing Widget Types\n", + "## Customizing Widget Placement\n", "\n", - "You can customize which widget class to use through the `widgets` parameter. For example, you might prefer a slider instead of a dropdown selector for better user experience." + "You can control where the widget appears using the [`widget_location`](option-widget_location) option. This is useful for creating layouts that work better with your specific visualization needs." ] }, { "cell_type": "code", "execution_count": null, - "id": "cc423294", + "id": "86fe3e21", "metadata": {}, "outputs": [], "source": [ - "import panel as pn\n", + "import hvplot.pandas # noqa\n", "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()\n", "penguins.hvplot.scatter(\n", " x='bill_length_mm',\n", " y='bill_depth_mm',\n", " groupby='species',\n", - " widgets={'species': pn.widgets.DiscreteSlider},\n", - " widget_location='top_left',\n", + " widget_location='top_left'\n", ")" ] }, @@ -117,9 +118,7 @@ "source": [ "## Exploring Multiple Dimensions\n", "\n", - "The penguins dataset has several categorical dimensions you can explore. Try grouping by different variables to discover patterns in the data:\n", - "\n", - "### Group by Island" + "The penguins dataset has several categorical dimensions you can explore. We can group by multiple dimensions at once to explore different combinations of the data:" ] }, { @@ -129,35 +128,14 @@ "metadata": {}, "outputs": [], "source": [ + "import hvplot.pandas # noqa\n", + "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()\n", + "# group by island and sex\n", "penguins.hvplot.scatter(\n", " x='flipper_length_mm',\n", " y='body_mass_g',\n", - " groupby='island',\n", - " width=400,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "4c2b848c", - "metadata": {}, - "source": [ - "### Group by Sex\n", - "\n", - "You can also explore differences between male and female penguins:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "35bbf39a", - "metadata": {}, - "outputs": [], - "source": [ - "penguins.hvplot.scatter(\n", - " x='bill_length_mm',\n", - " y='flipper_length_mm',\n", - " groupby='sex',\n", + " groupby=['island', 'sex'],\n", " color='species',\n", " width=400,\n", ")" diff --git a/doc/ref/api_compatibility/panel_widgets.ipynb b/doc/ref/api_compatibility/panel_widgets.ipynb index bec081d03..131125b68 100644 --- a/doc/ref/api_compatibility/panel_widgets.ipynb +++ b/doc/ref/api_compatibility/panel_widgets.ipynb @@ -16,7 +16,7 @@ "metadata": {}, "source": [ ":::{warning}\n", - "This functionality requires Panel to be installed. The API shown here may change in future versions.\n", + "The Panel APIs shown here may change in future versions.\n", ":::\n", ":::{note}\n", " When viewing on a static website, the widgets will be inoperable. To explore this functionality fully, download the notebook and run it in a live python environment.\n", diff --git a/doc/ref/plotting_options/data.ipynb b/doc/ref/plotting_options/data.ipynb index 83a2e6272..5e893bf5a 100644 --- a/doc/ref/plotting_options/data.ipynb +++ b/doc/ref/plotting_options/data.ipynb @@ -161,7 +161,7 @@ "(option-groupby)=\n", "## `groupby`\n", "\n", - "The `groupby` option specifies one or more dimensions by which to partition your data into separate groups. This grouping enables the creation of interactive widgets that let users filter or switch between different groups. When `dynamic=True` (the default), each group is rendered interactively as a HoloViews [`DynamicMap`](inv:holoviews#reference/containers/bokeh/DynamicMap), updating on-the-fly; otherwise, with `dynamic=False`, all groups are pre-rendered and returned as a [`HoloMap`](inv:holoviews#reference/containers/bokeh/HoloMap)." + "The `groupby` option specifies one or more dimensions by which to partition your data into separate groups. This grouping enables the creation of interactive widgets that let users filter or switch between different groups. When `dynamic=True` (the default), each group is rendered interactively as a HoloViews [`DynamicMap`](https://holoviews.org/reference_manual/holoviews.html#holoviews.DynamicMap), updating on-the-fly; otherwise, with `dynamic=False`, all groups are pre-rendered and returned as a [`HoloMap`](https://holoviews.org/reference_manual/holoviews.html#holoviews.HoloMap)." ] }, {