dash
Build production-grade interactive dashboards with Plotly Dash - enterprise features, callbacks, and scalable deployment
What this skill does
# Dash Production Dashboard Skill
Build enterprise-grade interactive dashboards with Plotly Dash. Features reactive callbacks, professional layouts, and scalable deployment for production workloads.
## When to Use This Skill
### USE Dash when:
- **Production dashboards** - Building dashboards for business users
- **Complex interactivity** - Need fine-grained control over updates
- **Enterprise requirements** - Authentication, scaling, reliability needed
- **Plotly ecosystem** - Already using Plotly for visualizations
- **Custom components** - Need to extend with JavaScript/React
- **Long-term projects** - Dashboard will be maintained and extended
- **Multi-user access** - Multiple concurrent users accessing dashboards
### DON'T USE Dash when:
- **Quick prototypes** - Use Streamlit for faster iteration
- **Simple visualizations** - Static reports may suffice
- **No interactivity needed** - Use static HTML/PDF reports
- **Limited Python knowledge** - Steeper learning curve than Streamlit
- **Single-user tools** - Jupyter notebooks may be simpler
## Prerequisites
```bash
# Basic installation
pip install dash
# With common extras
pip install dash plotly pandas dash-bootstrap-components
# Full installation
pip install dash plotly pandas polars dash-bootstrap-components dash-ag-grid gunicorn
# Using uv (recommended)
uv pip install dash plotly pandas dash-bootstrap-components dash-ag-grid
```
## Core Capabilities
### 1. Basic Application Structure
**Minimal Dash App:**
```python
from dash import Dash, html, dcc
import plotly.express as px
import pandas as pd
# Initialize app
app = Dash(__name__)
# Sample data
df = pd.DataFrame({
"Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
"Amount": [4, 1, 2, 2, 4, 5],
"City": ["SF", "SF", "SF", "NYC", "NYC", "NYC"]
})
# Create figure
fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")
# Layout
app.layout = html.Div([
html.H1("Hello Dash"),
html.P("This is a simple Dash application."),
dcc.Graph(id="example-graph", figure=fig)
])
# Run server
if __name__ == "__main__":
app.run(debug=True)
```
**Run the app:**
```bash
python app.py
# Visit http://127.0.0.1:8050/
```
### 2. Callbacks and Interactivity
**Basic Callback:**
```python
from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd
app = Dash(__name__)
# Sample data
df = pd.DataFrame({
"date": pd.date_range("2025-01-01", periods=100),
"category": ["A", "B", "C", "D"] * 25,
"value": range(100)
})
# Layout
app.layout = html.Div([
html.H1("Interactive Dashboard"),
html.Label("Select Category:"),
dcc.Dropdown(
id="category-dropdown",
options=[{"label": c, "value": c} for c in df["category"].unique()],
value="A",
clearable=False
),
dcc.Graph(id="line-chart")
])
# Callback
@callback(
Output("line-chart", "figure"),
Input("category-dropdown", "value")
)
def update_chart(selected_category):
filtered_df = df[df["category"] == selected_category]
fig = px.line(
filtered_df,
x="date",
y="value",
title=f"Values for Category {selected_category}"
)
return fig
if __name__ == "__main__":
app.run(debug=True)
```
**Multiple Inputs and Outputs:**
```python
from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd
app = Dash(__name__)
# Sample data
df = pd.DataFrame({
"date": pd.date_range("2025-01-01", periods=365),
"category": ["A", "B", "C"] * 122 + ["A"],
"region": ["North", "South", "East", "West"] * 91 + ["North"],
"value": [i + (i % 30) * 10 for i in range(365)]
})
app.layout = html.Div([
html.H1("Multi-Input Dashboard"),
html.Div([
html.Div([
html.Label("Category"),
dcc.Dropdown(
id="category-filter",
options=[{"label": c, "value": c} for c in df["category"].unique()],
value=["A", "B", "C"],
multi=True
)
], style={"width": "45%", "display": "inline-block"}),
html.Div([
html.Label("Region"),
dcc.Dropdown(
id="region-filter",
options=[{"label": r, "value": r} for r in df["region"].unique()],
value=["North", "South", "East", "West"],
multi=True
)
], style={"width": "45%", "display": "inline-block", "marginLeft": "5%"})
]),
html.Div([
html.Div([
dcc.Graph(id="trend-chart")
], style={"width": "60%", "display": "inline-block"}),
html.Div([
dcc.Graph(id="pie-chart")
], style={"width": "38%", "display": "inline-block", "marginLeft": "2%"})
]),
html.Div(id="summary-stats")
])
@callback(
[Output("trend-chart", "figure"),
Output("pie-chart", "figure"),
Output("summary-stats", "children")],
[Input("category-filter", "value"),
Input("region-filter", "value")]
)
def update_all(categories, regions):
# Filter data
filtered = df[
(df["category"].isin(categories)) &
(df["region"].isin(regions))
]
# Trend chart
trend = filtered.groupby("date")["value"].sum().reset_index()
trend_fig = px.line(trend, x="date", y="value", title="Value Trend")
# Pie chart
by_category = filtered.groupby("category")["value"].sum().reset_index()
pie_fig = px.pie(by_category, values="value", names="category", title="By Category")
# Summary stats
stats = html.Div([
html.H4("Summary Statistics"),
html.P(f"Total records: {len(filtered):,}"),
html.P(f"Total value: {filtered['value'].sum():,}"),
html.P(f"Average value: {filtered['value'].mean():.2f}")
])
return trend_fig, pie_fig, stats
if __name__ == "__main__":
app.run(debug=True)
```
**Chained Callbacks:**
```python
from dash import Dash, html, dcc, callback, Output, Input
import pandas as pd
app = Dash(__name__)
# Hierarchical data
data = {
"USA": {"California": ["San Francisco", "Los Angeles"], "Texas": ["Houston", "Dallas"]},
"Canada": {"Ontario": ["Toronto", "Ottawa"], "Quebec": ["Montreal", "Quebec City"]}
}
app.layout = html.Div([
html.H1("Chained Dropdowns"),
html.Label("Country"),
dcc.Dropdown(id="country-dropdown"),
html.Label("State/Province"),
dcc.Dropdown(id="state-dropdown"),
html.Label("City"),
dcc.Dropdown(id="city-dropdown"),
html.Div(id="selection-output")
])
# Populate country dropdown
@callback(
Output("country-dropdown", "options"),
Input("country-dropdown", "id") # Dummy input to trigger on load
)
def set_countries(_):
return [{"label": c, "value": c} for c in data.keys()]
# Update state options based on country
@callback(
Output("state-dropdown", "options"),
Output("state-dropdown", "value"),
Input("country-dropdown", "value")
)
def set_states(country):
if country is None:
return [], None
states = data.get(country, {}).keys()
return [{"label": s, "value": s} for s in states], None
# Update city options based on state
@callback(
Output("city-dropdown", "options"),
Output("city-dropdown", "value"),
Input("country-dropdown", "value"),
Input("state-dropdown", "value")
)
def set_cities(country, state):
if country is None or state is None:
return [], None
cities = data.get(country, {}).get(state, [])
return [{"label": c, "value": c} for c in cities], None
# Display selection
@callback(
Output("selection-output", "children"),
Input("country-dropdown", "value"),
Input("state-dropdown", "value"),
Input("city-dropdown", "value")
)
def display_selection(country, state, city):
return f"Selected: {country or '-'} > {state or '-'} > {city or '-'}"
if __name__ == "__main__":
app.run(debug=True)
```
### 3. Layout Components
**HTML Related in data-analysis
pandas
IncludedExpert data analysis and manipulation for customer support operations using pandas
autoviz
IncludedAutomatic exploratory data analysis and visualization with a single line of code - generates comprehensive charts, detects patterns, and exports to HTML/notebooks
great-tables
IncludedPublication-quality tables in Python with rich styling, formatting, conditional formatting, and export to HTML/images - inspired by R's gt package
polars
IncludedHigh-performance DataFrame library for fast data processing with lazy evaluation, parallel execution, and memory efficiency
streamlit
IncludedBuild interactive data applications and dashboards with pure Python - no frontend experience required
sweetviz
IncludedAutomated EDA comparison reports with target analysis, feature comparison, and HTML report generation for pandas DataFrames