3 Ways to Build a Panel Visualization Dashboard

hvPlot .interactive, Panel .bind, and Param .depends

Sophia Yang, Ph.D.
Towards Data Science

--

By Sophia Yang and Marc Skov Madsen

Are you interested in building an interactive dashboard in Python? Not only are there different tools you can use, even for a single tool like Panel there are multiple ways to build a dashboard. Would you like to find out why there are different options, and which approach is the best for your own use case? This article will walk you through three ways to create a Panel dashboard:

  • hvPlot .interactive turns any of your DataFrame processing pipelines into a dashboard (great if you want to explore a dataset!);
  • Panel .bind binds your widgets with your interactive plot (great if you want to build an arbitrary app!);
  • Param encapsulates your dashboard as self-contained classes (great if you want to build a complex codebase supporting both GUI and non-GUI usage).

We will show you how to choose the right approach for you and we will show you how to create this interactive dashboard with all three approaches:

What is Panel?

Panel is the dashboarding library in the open-source HoloViz ecosystem, which includes eight libraries (see Figure 1) and was developed by our Anaconda friends Philipp Rudiger, Jean-Luc Stevens, and Jim Bednar. With hundreds of thousands of downloads per month, HoloViz is the most popular Python visualization ecosystem.

Panel is designed to build custom interactive apps and dashboards. There are many Python visualization and dashboarding tools out there, each with its own benefits and special features. To learn more about the Python dashboarding landscape and find out which tool is the best for your use case, check out our previous blog post comparing the most popular dashboard-focused tools. Here, I will focus on Panel and show three very different ways to use it, so that you can see which one best matches your goals and situation.

Figure 1. Eight packages in the HoloViz ecosystem.

Data centered approach: hvPlot .interactive

hvPlot is the recommended entry point for plotting in the HoloViz ecosystem. If you know the Pandas or Xarray .plot API, you already know how to use hvPlot: just replace df.plot with df.hvplot.

hvPlot’s .interactive support is the best way to use Panel if you are mainly focused on exploring a dataset held in a Pandas or Dask DataFrame or an Xarray DataArray. With .interactive, you can very easily turn your processing pipeline into a Panel dashboard with just a few lines of code. To learn how hvPlot .interactive works in detail, please check out our previous blog post and video on this topic.

Below is the hvPlot .interactive code for creating the dashboard above. We will highlight some key points here:

  • hvPlot .interactive is data centered. Once you have a data frame, you can turn this data frame into an interactive data frame by calling idf=df.interactive().
  • In this code, we have defined three widgets cylinders, mfr, and yaxis so that our users can control these three values interactively. Then we can pass the widgets into a data processing pipeline, resulting in an interactive data processing pipeline ipipeline , and build an interactive plot iplot reflecting the values selected from the widgets.
  • We then used a template to display widgets in the sidebar and plot in the main body of the app.

Note that even if you do not have a data frame to start with, hvplot.bind(function, widget).interactive() can bind a function to a widget and make the bound function interactive. This functionality allows you to query data from a database or a web API, so that you can still use .interactive even if you don’t yet have your dataframe in hand.

Approach 1: hvplot .interactive (To run this script, first set up your environment by running `conda install hvplot panel` and then run `panel serve hvplot_interactive.py` in your command line)

App centered approach: pn .bind

What if you aren’t starting from a dataset that you are exploring, but instead you’ve written some function that returns something you want to display, with or without a dataset being involved?

Instead of starting with a data frame or a function that creates a data frame, pn .bind starts with a function. As you can see in the code below, the first 19 lines of importing packages and defining widgets are exactly the same as the previous approach. The difference starts from line 20, where we define a plot function that returns a plot (or anything else that Panel can display).

The magic happens when we use pn .bind to bind the plotting function plot with the widgets cylinders, mfr, yaxis. The result is an interactive plot interactive_plot:

interactive_plot = pn.bind(plot, cylinders, mfr, yaxis)

Approach 2: pn .bind (To run this script, first set up your environment by running `conda install hvplot panel` and then run `panel serve pn_bind.py` in your command line)

You can use pn.bind to “bind” widgets to any number of different functions, then lay out each “bound” function with Panel, so that the function is automatically invoked when any of the widgets bound to it is modified. This reactive-programming model lets you build just about any collection of widgets and outputs into a dashboard, making pn.bind an excellent approach if your goal is to build an app rather than to explore a dataset.

App centered approach: param .depends

What if you are mainly writing code for a research, analysis, scientific, or engineering domain, but you also want to support an optional GUI app interface? I.e., what if you need to maintain a single codebase that can be used either as a GUI or as a command-line, batch, or other automated process?

pn.bind can work well for such cases, if your code is primarily organized as Python functions; just put those functions into an importable file, then “bind” them to widgets in a separate app.py file to make the GUI version. What if your code is organized as Python classes? In that case, Panel is designed to work well with the param package, which lets you declare all of your code’s parameters in Python classes, then separately open a GUI for editing those values, while keeping your GUI and non-GUI code entirely independent.

As you can see in the code below, for this approach we create a class called InteractiveDashboard. Within this class, we create three parameters cylinders, mfr, yaxis. Note that these are abstract parameters, not Panel widgets, so that the code is not tied to any particular GUI framework. Crucially, we do not need to depend on Panel to call and use this class. We can use this dashboard class without using Panel or any other GUI library.

Similar to the pn .bind approach above, we use a plot function to create our plot. The @param.depends decorator lets us explicitly express the dependency between the plotting function and the parameters so that we know this plot depends on three widgets.

We instantiate this class by calling dashboard=InteractiveDashboard(). Then in the final step, we used a template to display parameters dashboard.param in the sidebar and plot dashboard.plot in the main body of the app.

Approach 3: param .depends (To run this script, first set up your environment by running `conda install hvplot panel param` and then run `panel serve param_depends.py` in your command line)

Which approach should you choose?

Are you doing data exploration?

If you are a data scientist or a data analyst working with a Pandas or Dask DataFrame or Xarray object, start with hvPlot .interactive. As a data scientist, I find hvPlot .interactive satisfies the majority of my dashboarding needs.

Code complexity:

hvPlot .interactive < Panel .bind < Param .depends

  • hvPlot .interactive is no doubt the easiest to learn and implement, and produces very short, readable code. It lives within the hvPlot framework. Even though it uses Panel to create a Panel dashboard, you don’t actually need to know much about Panel.
  • Panel .bind requires you to write functions, which is pretty easy as well, and is a better choice if you want to write an app that does a lot of computation that is not centered around dataframes.
  • Param .depends requires you to write classes, which is suited to the subset of people who are maintaining large, class-based Python codebases.

App flexibility:

hvPlot .interactive < Panel .bind < Param .depends

  • hvPlot .interactive is restricted to Pandas, Dask, Xarray DataFrame, or functions that produce such a data object.
  • Panel .bind can handle any arbitrary collection of objects and computations, but is specific to building an app.
  • The Param .depends approach lets you write code that supports a GUI but can also be used fully on its own, with no GUI dependencies.

Do you have questions?

Can I use Jupyter Notebook to make my app?

Yes, absolutely! One thing to call out is that all three example files we have shown above are .py files, but they can also be .ipynb files. So if you are a Jupyter Notebook user, you can create your dashboard in Jupyter Notebook and run panel serve filename.ipynbto serve your app.

What if I need more control? Should I use other supported approaches like pn .depends, pn .interact, param .watch, or a HoloViews DynamicMap?

Most users will be best served by one of the three methods mentioned in this document. pn.interact is provided mainly for migrating from ipywidets.interact, and is limited in what it can do. pn.bind supersedes pn.depends, supporting the same uses while also helping keep your GUI code isolated to the app instead of affecting your domain-specific computations. Param .watch is the underlying implementation of all of these approaches, and so you can use it if you need the very finest level of control over events and associated computation, but such control is only rarely needed even for complex apps. A HoloViews DynamicMap can be useful for optimizing your app to avoid flicker and provide fine-grained updates for portions of a plot, but it is much more difficult to describe than the approaches here, and not needed until you are ready to optimize for interactive performance.

Where can you learn more?

Hope you find this article helpful! If you have questions or want to connect to other HoloViz users check out https://discourse.holoviz.org/.

Acknowledgment:

Thank you Jim Bednar for the feedback and support!

References:

. . .

By Sophia Yang and Marc Skov Madsen on September 20, 2022.

Sophia Yang is a Senior Data Scientist at Anaconda. Connect with me on LinkedIn, Twitter, and YouTube and join the DS/ML Book Club ❤️

--

--