Add a web UI with Panel (basic)¶
Audience: Users who want to add a web UI written with Python and Panel.
Prereqs: Basic Python knowledge.
What is Panel?¶
Panel and the HoloViz ecosystem provide unique and powerful features such as big data visualization using DataShader, easy cross filtering using HoloViews, streaming and much more.
Panel is highly flexible and ties into the PyData and Jupyter ecosystems as you can develop in notebooks and use ipywidgets. You can also develop in .py files.
Panel is one of the most popular data app frameworks in Python with more than 400.000 downloads a month. It’s especially popular in the scientific community.
Panel is used, for example, by Rapids to power CuxFilter, a CuDF based big data visualization framework.
Panel can be deployed on your favorite server or cloud including Lightning.
Panel is particularly well suited for Lightning Apps that need to display live progress. This is because the Panel server can react to state changes and asynchronously push messages from the server to the client using web socket communication.
Install Panel with:
pip install panel
Run a basic Panel App¶
In the next few sections, we’ll build an App step-by-step.
First, create a file named app_panel.py
with the App content:
# app_panel.py
import panel as pn
pn.panel("Hello **Panel ⚡** World").servable()
Then, create a file named app.py
with the following App content:
# app.py
import lightning as L
from lightning.app.frontend import PanelFrontend
class LitPanel(L.LightningFlow):
def configure_layout(self):
return PanelFrontend("app_panel.py")
class LitApp(L.LightningFlow):
def __init__(self):
super().__init__()
self.lit_panel = LitPanel()
def run(self):
self.lit_panel.run()
def configure_layout(self):
return {"name": "home", "content": self.lit_panel}
app = L.LightningApp(LitApp())
Finally, add panel
to your requirements.txt
file:
echo 'panel' >> requirements.txt
Note
This is a best practice to make Apps reproducible.
Run the App¶
Run the App locally:
lightning_app run app app.py
The App should look like this:
Now, run it on the cloud:
lightning_app run app app.py --cloud
Step-by-step walk-through¶
In this section, we explain each part of the code in detail.
0. Define a Panel app¶
First, find the Panel app you want to integrate. In this example, that app looks like:
import panel as pn
pn.panel("Hello **Panel ⚡** World").servable()
Refer to the Panel documentation and awesome-panel for more complex examples.
1. Add Panel to a Component¶
Link this app to the Lightning App by using the PanelFrontend
class which needs to be returned from
the configure_layout
method of the Lightning Component you want to connect to Panel.
import lightning as L
from lightning.app.frontend import PanelFrontend
class LitPanel(L.LightningFlow):
def configure_layout(self):
return PanelFrontend("app_panel.py")
class LitApp(L.LightningFlow):
def __init__(self):
super().__init__()
self.lit_panel = LitPanel()
def run(self):
self.lit_panel.run()
def configure_layout(self):
return {"name": "home", "content": self.lit_panel}
app = L.LightningApp(LitApp())
The argument of the PanelFrontend
class, points to the script, notebook, or function that
runs your Panel app.
2. Route the UI in the root component¶
The second step, is to tell the Root component in which tab to render this component’s UI.
In this case, we render the LitPanel
UI in the home
tab of the app.
import lightning as L
from lightning.app.frontend import PanelFrontend
class LitPanel(L.LightningFlow):
def configure_layout(self):
return PanelFrontend("app_panel.py")
class LitApp(L.LightningFlow):
def __init__(self):
super().__init__()
self.lit_panel = LitPanel()
def run(self):
self.lit_panel.run()
def configure_layout(self):
return {"name": "home", "content": self.lit_panel}
app = L.LightningApp(LitApp())
Tips & Tricks¶
0. Use autoreload while developing¶
To speed up your development workflow, you can run your Lightning App with Panel autoreload by
setting the environment variable PANEL_AUTORELOAD
to yes
.
Try running the following:
PANEL_AUTORELOAD=yes lightning run app app.py
1. Theme your App¶
To theme your App you, can use the Lightning accent color #792EE5
with the FastListTemplate.
Try replacing the contents of app_panel.py
with the following:
# app_panel.py
import panel as pn
import plotly.express as px
ACCENT = "#792EE5"
pn.extension("plotly", sizing_mode="stretch_width", template="fast")
pn.state.template.param.update(
title="⚡ Hello Panel + Lightning ⚡", accent_base_color=ACCENT, header_background=ACCENT
)
pn.config.raw_css.append(
"""
.bk-root:first-of-type {
height: calc( 100vh - 200px ) !important;
}
"""
)
def get_panel_theme():
"""Returns 'default' or 'dark'"""
return pn.state.session_args.get("theme", [b"default"])[0].decode()
def get_plotly_template():
if get_panel_theme() == "dark":
return "plotly_dark"
return "plotly_white"
def get_plot(length=5):
xseries = [index for index in range(length + 1)]
yseries = [x**2 for x in xseries]
fig = px.line(
x=xseries,
y=yseries,
template=get_plotly_template(),
color_discrete_sequence=[ACCENT],
range_x=(0, 10),
markers=True,
)
fig.layout.autosize = True
return fig
length = pn.widgets.IntSlider(value=5, start=1, end=10, name="Length")
dynamic_plot = pn.panel(
pn.bind(get_plot, length=length), sizing_mode="stretch_both", config={"responsive": True}
)
pn.Column(length, dynamic_plot).servable()
Install some additional libraries and remember to add the dependencies to the requirements.txt
file:
echo 'plotly' >> requirements.txt
echo 'pandas' >> requirements.txt
Finally run the App
lightning_app run app app.py