Dashboards (Streamlit / Dash / Gradio)
Turn notebooks into shareable apps: Streamlit for rapid data dashboards, Dash for Plotly-centric products, Gradio for model demos.
Search across all documentation pages
Turn notebooks into shareable apps: Streamlit for rapid data dashboards, Dash for Plotly-centric products, Gradio for model demos.
Quick-reference recipe card - copy-paste ready.
# streamlit_app.py
import streamlit as st
import pandas as pd
@st.cache_data
def load():
return pd.read_parquet("sales.parquet")
df = load()
region = st.selectbox("Region", sorted(df["region"].unique()))
filtered = df[df["region"] == region]
st.line_chart(filtered.set_index("ordered_at")["revenue"])When to reach for this:
# Minimal Streamlit + Plotly pattern
import streamlit as st
import pandas as pd
import plotly.express as px
st.set_page_config(page_title="Revenue Explorer", layout="wide")
@st.cache_data(show_spinner="Loading sales...")
def load_sales() -> pd.DataFrame:
# Replace with read_parquet in production
return pd.DataFrame(
{
"ordered_at": pd.date_range("2025-01-01", periods=30, freq="D", tz="UTC"),
"region": ["East", "West"] * 15,
"revenue": range(30),
}
)
df = load_sales()
col1, col2 = st.columns(2)
with col1:
regions = st.multiselect("Regions", sorted(df["region"].unique()), default=["East"])
with col2:
min_rev = st.slider("Min revenue", 0, int(df["revenue"].max()), 0)
filtered = df[df["region"].isin(regions) & (df["revenue"] >= min_rev)]
fig = px.line(filtered, x="ordered_at", y="revenue", color="region")
st.plotly_chart(fig, use_container_width=True)
st.dataframe(filtered, use_container_width=True)What this demonstrates:
cache_data avoids reloading Parquet on every widget changepredict(image) -> label.uvicorn/built-in server - put reverse proxy auth in production.| Framework | Sweet spot |
|---|---|
| Streamlit | pandas/plots + filters in hours |
| Dash | Multi-page Plotly apps, enterprise |
| Gradio | Hugging Face model demos |
# Dash skeleton (separate app.py)
from dash import Dash, html, dcc, Input, Output
import plotly.express as px
app = Dash(__name__)
app.layout = html.Div([dcc.Graph(id="chart"), dcc.Dropdown(id="region")])
# @app.callback(Output("chart", "figure"), Input("region", "value")) ...@st.cache_data / Dash dcc.Store.st.secrets or env vars only. Fix: never commit credentials.| Alternative | Use When | Don't Use When |
|---|---|---|
| Panel/HoloViz | PyData stack integration | Team wants simplest path (Streamlit) |
| FastAPI + React | Custom UX and auth | Need app in one afternoon |
| Superset/Metabase | Warehouse BI on SQL | Heavy Python transforms in UI |
| Observable / Hex | Hosted notebook products | Self-hosted Python requirement |
streamlit run app.py --server.port=8501.import gradio as gr
demo = gr.Interface(fn=predict, inputs="image", outputs="label")
demo.launch()share=True only for demos, not production data.st.line_chart or use Plotly/Altair directly.dash.testing fixtures.DATA_DT=2025-01-15).Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 19, 2026