diff --git a/doc/explanation/index.md b/doc/explanation/index.md new file mode 100644 index 000000000..5af3e7348 --- /dev/null +++ b/doc/explanation/index.md @@ -0,0 +1,10 @@ +# 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 + +``` diff --git a/doc/how_to/create_advanced_layouts.ipynb b/doc/how_to/create_advanced_layouts.ipynb new file mode 100644 index 000000000..803827dea --- /dev/null +++ b/doc/how_to/create_advanced_layouts.ipynb @@ -0,0 +1,284 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8597e294", + "metadata": {}, + "source": [ + "# How to Create Advanced Plot Layouts\n", + "\n", + "This guide shows you how to create sophisticated plot layouts using hvPlot and Panel for more complex arrangements beyond basic subplots and grids.\n", + "\n", + "## When to use advanced layouts\n", + "\n", + "Use advanced layouts when:\n", + "- You need precise control over plot positioning and sizing beyond basic faceting\n", + "- You want to combine different types of visualizations (plots, tables, widgets)\n", + "- You need interactive dashboards with custom arrangements\n", + "- Basic subplots and grids don't provide the flexibility you need" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e4ffad99", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.pandas # noqa\n", + "import panel as pn\n", + "\n", + "pn.extension('tabulator')\n", + "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna().reset_index(drop=True)\n", + "stocks = hvplot.sampledata.stocks(\"pandas\")\n", + "earthquakes = hvplot.sampledata.earthquakes(\"pandas\")" + ] + }, + { + "cell_type": "markdown", + "id": "96dc3ecf", + "metadata": {}, + "source": [ + "## Using the `+` operator for side-by-side layouts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ded095ba", + "metadata": {}, + "outputs": [], + "source": [ + "size_opts = {\"frame_width\": 250, \"aspect\": \"square\"}\n", + "\n", + "scatter = penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " color='species',\n", + " title='Bill Dimensions',\n", + " **size_opts\n", + ")\n", + "hist = penguins.hvplot.hist(\n", + " y='body_mass_g',\n", + " by='species',\n", + " title='Body Mass Distribution',\n", + " **size_opts\n", + ")\n", + "\n", + "scatter + hist" + ] + }, + { + "cell_type": "markdown", + "id": "276c2afe", + "metadata": {}, + "source": [ + "## Using the `*` operator for overlays" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6810b4f", + "metadata": {}, + "outputs": [], + "source": [ + "line_plot = stocks.hvplot.line(x='date', y='Apple', label=\"Line\")\n", + "scatter_plot = stocks[::20].hvplot.scatter(x='date', y='Apple', color=\"red\",\n", + " size=50, alpha=0.7, label=\"Marker\")\n", + "\n", + "line_plot * scatter_plot" + ] + }, + { + "cell_type": "markdown", + "id": "f377395b", + "metadata": {}, + "source": [ + "### Complex layouts with custom arrangements" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f8ccd32a", + "metadata": {}, + "outputs": [], + "source": [ + "size_opts = {\"frame_width\": 250, \"aspect\": \"square\"}\n", + "\n", + "p1 = penguins.hvplot.scatter(x='bill_length_mm', y='bill_depth_mm',\n", + " color='species', size=80, alpha=0.7,\n", + " title='Bill Dimensions', **size_opts)\n", + "\n", + "p2 = penguins.hvplot.scatter(x='flipper_length_mm', y='body_mass_g',\n", + " color='species', size=80, alpha=0.7,\n", + " title='Size Measurements', **size_opts)\n", + "\n", + "p3 = penguins.hvplot.box(y='bill_length_mm', by='species',\n", + " title='Bill Length by Species', **size_opts)\n", + "\n", + "p4 = penguins.hvplot.violin(y='body_mass_g', by='species',\n", + " title='Body Mass Distribution', **size_opts)\n", + "\n", + "\n", + "layout = (p1 + p2 + p3 + p4).cols(2)\n", + "layout" + ] + }, + { + "cell_type": "markdown", + "id": "2105758a", + "metadata": {}, + "source": [ + "## Panel Layouts for Dashboard Creation\n", + "\n", + "Panel provides even more flexibility for creating complex dashboards:\n", + "\n", + "### Basic Panel layouts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "df356385", + "metadata": {}, + "outputs": [], + "source": [ + "trend_plot = stocks.hvplot.line(x='date', title='Stock Trends', height=300)\n", + "\n", + "correlation_plot = hvplot.plotting.scatter_matrix(stocks, alpha=0.5)\n", + "\n", + "# Create a Panel Column layout\n", + "pn.Column(trend_plot, correlation_plot)" + ] + }, + { + "cell_type": "markdown", + "id": "736a01b8", + "metadata": {}, + "source": [ + "### Combining plots with data tables" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3368427e", + "metadata": {}, + "outputs": [], + "source": [ + "summary_plot = earthquakes.hvplot.scatter(x='lon', y='lat', color='mag',\n", + " size='mag', alpha=0.7,\n", + " title='Earthquake Locations',\n", + " frame_height=300, aspect='square',\n", + " tiles=True)\n", + "\n", + "data_table = pn.widgets.Tabulator(earthquakes, height=400, width=400,\n", + " pagination='remote', page_size=10)\n", + "\n", + "pn.Row(summary_plot, data_table)" + ] + }, + { + "cell_type": "markdown", + "id": "7bf9ee23", + "metadata": {}, + "source": [ + "### Creating tabbed layouts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b20ecfc6", + "metadata": {}, + "outputs": [], + "source": [ + "overview_tab = penguins.hvplot.scatter(x='bill_length_mm', y='bill_depth_mm',\n", + " color='species', size=80, alpha=0.7,\n", + " title='Species Overview')\n", + "\n", + "detailed_tab = penguins.hvplot.scatter(x='bill_length_mm', y='bill_depth_mm',\n", + " by='species', subplots=True,\n", + " width=250, height=200, alpha=0.7)\n", + "\n", + "data_tab = pn.widgets.Tabulator(penguins, pagination='remote', page_size=10)\n", + "\n", + "tabs = pn.Tabs(\n", + " ('Overview', overview_tab),\n", + " ('Detailed View', detailed_tab),\n", + " ('Data Table', data_tab)\n", + ")\n", + "tabs" + ] + }, + { + "cell_type": "markdown", + "id": "1ff9aaa7", + "metadata": {}, + "source": [ + "### Advanced Panel layouts with custom sizing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7a26cb55", + "metadata": {}, + "outputs": [], + "source": [ + "main_plot = stocks.hvplot.line(x='date', y=['Apple', 'Google'], title='Main Trends')\n", + "\n", + "side_plot1 = stocks.hvplot.hist(y='Apple', title='Apple Distribution',\n", + " height=170, width=340)\n", + "\n", + "side_plot2 = stocks.hvplot.hist(y='Google', title='Google Distribution',\n", + " height=170, width=340)\n", + "\n", + "# Create complex layout\n", + "layout = pn.Column(\n", + " main_plot,\n", + " pn.Row(side_plot1, side_plot2)\n", + ")\n", + "layout" + ] + }, + { + "cell_type": "markdown", + "id": "18e62ac5", + "metadata": {}, + "source": [ + "## Best practices for advanced layouts\n", + "\n", + "1. **Start simple**: Begin with basic layouts and add complexity gradually\n", + "2. **Consider screen size**: Test your layouts on different screen sizes\n", + "3. **Use consistent sizing**: Maintain visual harmony with consistent dimensions\n", + "4. **Optimize for your use case**: Choose HvPlot/HoloViews for analysis and basic faceting, Panel for dashboards\n", + "\n", + ":::{admonition} Summary\n", + "\n", + "- Use `+` operator for side-by-side layouts\n", + "- Use `*` operator for overlays\n", + "- Panel provides `Row`, `Column`, and `Tabs` for complex dashboard layouts\n", + "- Panel can combine plots with tables, widgets, and other components\n", + "- Use `responsive=True` and Panel's sizing modes for adaptive layouts\n", + ":::\n", + "\n", + ":::{admonition} Further Reading\n", + ":class: seealso\n", + "See the [Panel layouts tutorial](https://panel.holoviz.org/tutorials/basic/layouts.html) for more on layouting Python objects\n", + ":::" + ] + } + ], + "metadata": { + "language_info": { + "name": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/how_to/create_basic_subplots.ipynb b/doc/how_to/create_basic_subplots.ipynb new file mode 100644 index 000000000..22ab674af --- /dev/null +++ b/doc/how_to/create_basic_subplots.ipynb @@ -0,0 +1,179 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "23258cf2", + "metadata": {}, + "source": [ + "# How to Create Basic Subplots\n", + "\n", + "This guide shows you how to facet your data into separate subplots instead of overlaying them on a single axis. This is useful when you want to compare multiple variables or categories side by side.\n", + "\n", + "## When to use subplots\n", + "\n", + "Use subplots when:\n", + "- You want to compare multiple variables with different scales\n", + "- You need to avoid visual clutter from overlapping lines or points\n", + "- You want to highlight patterns in individual variables\n", + "\n", + "## Setup\n", + "\n", + "First, let's load some sample datasets from the `hvsampledata` module:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27271ae7", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.pandas # noqa\n", + "\n", + "stocks = hvplot.sampledata.stocks(\"pandas\")\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()" + ] + }, + { + "cell_type": "markdown", + "id": "78b0c591", + "metadata": {}, + "source": [ + "## Default behavior: Overlaid plots\n", + "\n", + "By default, hvPlot overlays multiple columns onto one axis for easy comparison:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eecbe872", + "metadata": {}, + "outputs": [], + "source": [ + "stocks.hvplot(x='date', value_label='Stock Price', title='Relative Stock Prices')" + ] + }, + { + "cell_type": "markdown", + "id": "6c1e32ef", + "metadata": {}, + "source": [ + "## Creating subplots with subplots=True\n", + "\n", + "To split each column into its own separate plot, set `subplots=True`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9183b5c8", + "metadata": {}, + "outputs": [], + "source": [ + "stocks.hvplot(\n", + " x='date',\n", + " value_label='Stock Price',\n", + " subplots=True,\n", + " width=250,\n", + " height=200,\n", + ").cols(3)" + ] + }, + { + "cell_type": "markdown", + "id": "1415cdb5", + "metadata": {}, + "source": [ + "## Controlling axis sharing\n", + "\n", + "By default, subplots have linked, normalized axes to facilitate comparison. You can pan or zoom in any plot to see how the others change.\n", + "\n", + "However, if your data covers widely different numerical ranges, use `shared_axes=False` to give each plot its own range:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "651df41d", + "metadata": {}, + "outputs": [], + "source": [ + "penguin_cols = penguins[\n", + " ['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g']\n", + " ]\n", + "\n", + "penguin_cols.hvplot(\n", + " kind='hist',\n", + " subplots=True,\n", + " shared_axes=False,\n", + " frame_height=200,\n", + " aspect='square',\n", + " alpha=0.7\n", + ").cols(2)" + ] + }, + { + "cell_type": "markdown", + "id": "7dcbb62a", + "metadata": {}, + "source": [ + "Notice how each histogram has its own appropriate scale, making it easier to see the distribution patterns.\n", + "\n", + ":::{tip}\n", + "Use `.cols(n)` to specify how many plots per row before wrapping to the next line\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "id": "63a4539d", + "metadata": {}, + "source": [ + "## Using subplots with grouping (`by` parameter)\n", + "\n", + "You can combine `subplots=True` with the `by` keyword to create separate plots for each group. This is a form of categorical faceting:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ce5b1b2", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " by='species',\n", + " subplots=True,\n", + " width=250,\n", + " height=200,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "831403fd", + "metadata": {}, + "source": [ + ":::{admonition} Summary\n", + "\n", + "- Use `subplots=True` to create separate plots (facets) instead of overlaying them\n", + "- Use `shared_axes=False` when your data has very different scales\n", + "- Subplots with shared axes allow linked panning and zooming for easy comparison\n", + "- Use `.cols(n)` to control the layout and number of plots per row\n", + "- Combine with `by` parameter to create subplots for different groups (categorical faceting)\n", + ":::" + ] + } + ], + "metadata": { + "language_info": { + "name": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/how_to/create_plot_grids.ipynb b/doc/how_to/create_plot_grids.ipynb new file mode 100644 index 000000000..12295d853 --- /dev/null +++ b/doc/how_to/create_plot_grids.ipynb @@ -0,0 +1,218 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2b241557", + "metadata": {}, + "source": [ + "# How to Create Plot Grids\n", + "\n", + "This guide shows you how to arrange multidimensional data into explicit grids of plots with shared axes, allowing easier comparisons across large numbers of related plots.\n", + "\n", + "## When to use plot grids\n", + "\n", + "Use plot grids when:\n", + "- You have multidimensional data that naturally forms a matrix structure\n", + "- You want shared axes across rows and columns for easy comparison\n", + "- You need to visualize patterns across multiple categorical variables simultaneously\n", + "\n", + "## Setup\n", + "\n", + "Let's load some sample datasets from the `hvsampledata` module:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e99b3c25", + "metadata": {}, + "outputs": [], + "source": [ + "import hvplot.pandas # noqa\n", + "import hvplot.xarray # noqa\n", + "\n", + "penguins = hvplot.sampledata.penguins(\"pandas\").dropna()\n", + "air_temp = hvplot.sampledata.air_temperature(\"xarray\")" + ] + }, + { + "cell_type": "markdown", + "id": "e6ff304e", + "metadata": {}, + "source": [ + ":::{note}\n", + "`subplots=True` lays out plots sequentially and formats each plot independently, while grids arrange data into explicit rows and columns with shared axes. This is the difference between simple faceting and grid-based faceting.\n", + ":::\n", + "\n", + "## Creating a simple row of plots\n", + "\n", + "Use the `col` parameter to create a horizontal row of plots:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d57c2ac", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " col='species',\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "e10b6e14", + "metadata": {}, + "source": [ + "## Creating a 2D grid of plots\n", + "\n", + "Use both `row` and `col` parameters to create a 2D grid. This is powerful for exploring relationships across multiple categorical dimensions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92c00b59", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.scatter(\n", + " x='bill_length_mm',\n", + " y='bill_depth_mm',\n", + " row='sex',\n", + " col='species',\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "07363b2e", + "metadata": {}, + "source": [ + "Notice how the axis ticks and labels are shared across the grid. This saves space and makes comparisons easier compared to individual subplots.\n", + "\n", + "## Working with gridded data\n", + "\n", + "Grids are particularly useful for multidimensional arrays. Let's use the air temperature dataset:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "190a86ce", + "metadata": {}, + "outputs": [], + "source": [ + "# Select a subset of time steps for visualization\n", + "air_subset = air_temp.isel(time=[0, 1])\n", + "\n", + "air_subset.hvplot(col='time', cmap='viridis', frame_width=200)" + ] + }, + { + "cell_type": "markdown", + "id": "401833bc", + "metadata": {}, + "source": [ + "## Customizing grid appearance\n", + "\n", + "You can disable axes entirely if they're not needed for your visualization:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf92fa87", + "metadata": {}, + "outputs": [], + "source": [ + "air_subset.hvplot(\n", + " col='time',\n", + " xaxis=False,\n", + " yaxis=False,\n", + " colorbar=False,\n", + " cmap='viridis',\n", + " frame_width=200,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "dfbb510f", + "metadata": {}, + "source": [ + "## Advanced grid layouts\n", + "\n", + "You can create more complex arrangements by combining multiple categorical variables:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f98864f5", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.box(\n", + " y='body_mass_g',\n", + " by='species',\n", + " col='sex',\n", + " frame_width=200,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "3a41958e", + "metadata": {}, + "source": [ + "## Combining grid layouts with statistical plots\n", + "\n", + "Grids work well with various plot types, including statistical visualizations:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5636e09", + "metadata": {}, + "outputs": [], + "source": [ + "penguins.hvplot.hist(\n", + " y='flipper_length_mm',\n", + " by='species',\n", + " col='sex',\n", + " bins=15,\n", + " frame_width=200,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a5a52999", + "metadata": {}, + "source": [ + ":::{admonition} Summary\n", + "\n", + "- Use `col` parameter to create a row of plots with shared axes\n", + "- Use both `row` and `col` to create a 2D grid of plots\n", + "- Grids automatically share axes across rows and columns for easy comparison\n", + "- Use `xaxis=False` and `yaxis=False` to create cleaner visualizations when axes aren't needed\n", + "- Grids work with any plot type and are particularly powerful for multidimensional data\n", + "- Grid layouts save space and facilitate pattern recognition across multiple dimensions" + ] + } + ], + "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 new file mode 100644 index 000000000..7d8c49d53 --- /dev/null +++ b/doc/how_to/index.md @@ -0,0 +1,17 @@ +# 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. + +## Plot Layout and Organization + +Learn how to organize and arrange your plots for better visualization and comparison. + +```{toctree} +:titlesonly: +:hidden: +:maxdepth: 2 + +create_basic_subplots +create_plot_grids +create_advanced_layouts +``` diff --git a/doc/index.md b/doc/index.md index e868f5cec..5340961fd 100644 --- a/doc/index.md +++ b/doc/index.md @@ -434,8 +434,10 @@ align: center Tutorials User Guide +How-To Guides Gallery Reference +Explanation Developer Guide Releases Roadmap