Build an app#

At this point you should have set up your environment and installed Panel so you should be ready to get going.

On this page, we’re going to be building a basic interactive application based on Numpy, Pandas and hvplot. If you want to implement this app yourself as you follow along, we recommend starting with a Jupyter notebook. You can also launch the Notebook with JupyterLite on the right.

Fetch the data#

First let’s load the UCI ML dataset that measured the environment in a meeting room:

Important

At first, this website renders code block outputs with limited interactivity, indicated by the golden border to the left of the output below. By clicking the play button ( ) you can activate full interactivity, indicated by a green left-border.

import panel as pn
import hvplot.pandas
import pandas as pd
import numpy as np

pn.extension(design='material')

csv_file = ("https://raw.githubusercontent.com/holoviz/panel/main/examples/assets/occupancy.csv")
data = pd.read_csv(csv_file, parse_dates=["date"], index_col="date")

data.tail()
Temperature Humidity Light CO2 HumidityRatio Occupancy
date
2015-02-10 09:29:00 21.05 36.0975 433.0 787.250000 0.005579 1
2015-02-10 09:29:59 21.05 35.9950 433.0 789.500000 0.005563 1
2015-02-10 09:30:59 21.10 36.0950 433.0 798.500000 0.005596 1
2015-02-10 09:32:00 21.10 36.2600 433.0 820.333333 0.005621 1
2015-02-10 09:33:00 21.10 36.2000 447.0 821.000000 0.005612 1

Visualize a subset of the data#

Before we utilize Panel, let’s write a function that smooths one of our time series and finds the outliers. We will then plot the result using hvplot.

def transform_data(variable, window, sigma):
    ''' Calculates the rolling average and the outliers '''
    avg = data[variable].rolling(window=window).mean()
    residual = data[variable] - avg
    std = residual.rolling(window=window).std()
    outliers = np.abs(residual) > std * sigma
    return avg, avg[outliers]

def create_plot(variable="Temperature", window=30, sigma=10):
    ''' Plots the rolling average and the outliers '''
    avg, highlight = transform_data(variable, window, sigma)
    return avg.hvplot(height=300, width=400, legend=False) * highlight.hvplot.scatter(
        color="orange", padding=0.1, legend=False
    )

We can now call our create_plot function with specific parameters to get a plot with a single set of parameters.

create_plot(variable='Temperature', window=20, sigma=10)

It works! But now we want explore how values for window and sigma affect the plot. We could reevaluate the above cell a lot of times, but that would be a slow and painful process. Instead, let’s use Panel to quickly add some interactive controls and quickly determine how different parameter values impact the output.

Explore parameter space#

Let’s create some Panel slider widgets for the range of parameter values that we want to explore.

variable_widget = pn.widgets.Select(name="variable", value="Temperature", options=list(data.columns))
window_widget = pn.widgets.IntSlider(name="window", value=30, start=1, end=60)
sigma_widget = pn.widgets.IntSlider(name="sigma", value=10, start=0, end=20)

Now that we have a function and some widgets, let’s link them together so that updates to the widgets rerun the function. One easy way to create this link in Panel is with pn.bind:

bound_plot = pn.bind(create_plot, variable=variable_widget, window=window_widget, sigma=sigma_widget)

Once you have bound the widgets to the function’s arguments you can lay out the resulting bound_plot component along with the widget components using a Panel layout such as Column:

first_app = pn.Column(variable_widget, window_widget, sigma_widget, bound_plot)

first_app

As long as you have a live Python process running, dragging these widgets will trigger a call to the create_plot callback function, evaluating it for whatever combination of parameter values you select and displaying the results.

Next Steps#

Now that we have given you a taste of how easy it is to build a little application in Panel, it’s time to introduce you to some of the core concepts behind Panel.