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.