Open this notebook in Jupyterlite | Download this notebook from GitHub (right-click to download).

import panel as pn
import param


The panel.ReactiveExpr pane renders a Param rx object which represents a reactive expression, displaying both the widgets that are part of the expression and the final output of the expression. The position of the widgets relative to the output can be set, or widgets can be removed entirely. See the Param documentation on param.rx for details on using rx.


The basic parameters are:

  • object (param.reactive): A param.reactive expression

The more advanced parameters which give you more control are:

  • default_layout (panel.layout.base.ListPanel): A layout like Column, Row, etc. or a GridBox.

  • center (bool): Whether to center the output.

  • show_widgets (bool): Whether to display the widget inputs.

  • widget_layout (panel.layout.base.ListPanel): The layout object to display the widgets in.

  • widget_location (str): The location of the widgets relative to the output of the reactive expression. One of ‘left’, ‘right’, ‘top’, ‘bottom’, ‘top_left’, ‘top_right’, ‘bottom_left’, ‘bottom_right’, ‘left_top’ (default), ‘right_top’,right_bottom’.

For more layout and styling related parameters see the customization user guide.

The param.rx API is a powerful tool for building declarative and reactive UIs and the ReactiveExpr pane allows turning these declarative expressions into viewable components that render both the (widget) inputs and the outputs of the expression:

v1 = pn.widgets.FloatInput(value=35)
v2 = pn.widgets.FloatInput(value=7)

expr = v1.rx() + v2.rx()


When Panel is imported an rx expression will automatically be rendered using the ReactiveExpr object, i.e. displaying expr on its own or putting it in a layout is exactly equivalent to the version above.


Note that this is different from using the expression as a reference, i.e. passing it to another component for it to resolve the value of the expression dynamically:

pn.Row(v1, '`+`', v2, '`=`', pn.pane.Str(expr))

The reference approach should generally be preferred as it is more declarative and explicit, allowing Panel to efficiently update the existing view(s) rather than completely re-rendering the output.

The ReactiveExpr pane is therefore primarily a way to quickly and interactively work with an expression (particularly in a notebook) or generate a quick UI for a data pipeline. Once you have built the expression and want to integrate it in a larger application it is generally recommended that you use it as a reference as to narrowly scope the precise updates you want to make.

Let us work through this in a slightly more complex example, and build an expression to dynamically load some data and sample N rows from it:

import pandas as pd

dataset = pn.widgets.Select(name='Pick a dataset', options={
    'penguins': '',
    'stocks': ''
nrows = pn.widgets.IntSlider(value=5, start=0, end=20, name='N rows')

# Load the currently selected dataset and sample nrows from it
df_rx = pn.bind(pd.read_csv, dataset).rx().sample(n=nrows)


Now that we have an expression that does what we want we can use it as a reference to reactive update the value of a Tabulator widget:

table = pn.widgets.Tabulator(df_rx, page_size=5, pagination='remote')'RdYlGn_r')

pn.Row(pn.Column(dataset, nrows), table)

However, particularly for complex expressions with tons of inputs it may still be useful to use the ReactiveExpr object to render all the widget inputs:

pn.Row(pn.ReactiveExpr(df_rx).widgets, table)

Open this notebook in Jupyterlite | Download this notebook from GitHub (right-click to download).