Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
holoviz
GitHub Repository: holoviz/panel
Path: blob/main/doc/how_to/interactivity/hvplot_interactive.md
2012 views

Make interactive data workflows

This guide addresses how to bind interactive data pipelines to a component using the Reactive Expressions of Param.


The Param rx object allows you to treat any object as a reactive expression. This is done by replacing the constant parameters in your pipeline with widgets (e.g., a number slider) that will trigger an output update on changes. With this approach, all your pipeline parameters are available in one place, and you get complete interactive control over the pipeline. For convenience, we could use pn.rx instead of param.rx when you import panel as pn.

Let's start by fetching some data:

import pandas as pd df = pd.read_csv('https://datasets.holoviz.org/penguins/v1/penguins.csv') df.head()

We now want to create select widgets for the column species and a slider for year. We can do this with Panel's widgets:

import panel as pn pn.extension('tabulator') species_widget = pn.widgets.Select(name="species", options=["Adelie", "Gentoo", "Chinstrap"]) year_widget = pn.widgets.IntSlider(name="year", start=2007, end=2009)

Let's then use these to filter the data. We first wrap the df in pn.rx as df_rx and pass the species_widget as the species parameter and the year_widget as the year parameter. In our case, we want the year always to be greater than or equal to the widget's value.

import hvplot.pandas # Enable interactive df_rx = pn.rx(df) df_rx = df_rx[(df_rx["species"] == species_widget) & (df_rx["year"] >= year_widget)] df_rx.head()

Similarly we can use other pandas features in the same way.

head_widget = pn.widgets.IntSlider(name="Head", start=1, end=10) df_rx.head(head_widget)

Because we've imported hvplot.pandas, we can utilize .hvplot() to render the widgets and plot the data easily:

df_rx.hvplot(kind="scatter", x="bill_length_mm", y="bill_depth_mm", by="sex")

We can leverage panel.ReactiveExpr to assist in rendering df_rx. This allows us to include all widgets related to df_rx, while also offering the flexibility to customize the appearance of the widgets. For instance, we can specify pn.Column as the widget_layout parameter and top as the widget_location parameter, as shown below:

pn.ReactiveExpr( df_rx.head(), # only show a few rows to save some space widget_layout=pn.Column, widget_location="top", )

While panel.ReactiveExpr offers convenience, it's also common practice to bind the interactive pipeline we've constructed to a Panel component, such as a Tabulator widget:

table = pn.widgets.Tabulator(df_rx, page_size=10, pagination="remote") pn.Column(species_widget, year_widget, table)

Notably, with this approach, we need to handle the layout of widgets ourselves.

For complex expressions involving many widgets, the panel.ReactiveExpr pane offers a .widgets attribute, returning a ListPanel, which helps us retrieve all the related widgets. Once we have access to the widgets, it becomes possible to reposition them or add custom widgets in the final layout.

widgets = pn.ReactiveExpr(df_rx).widgets pn.Column( pn.WidgetBox(*reversed(widgets)), pn.Spacer(height=30), table, )

Finally, if performance is critical, you might want to consider using Reactive expressions as references. For instance, you can try replacing df_rx with df_rx.rx() in this tutorial.