Claude
Skills
Sign in
Back

dash

Included with Lifetime
$97 forever

Build production-grade interactive dashboards with Plotly Dash - enterprise features, callbacks, and scalable deployment

data-analysisdashdashboardplotlycallbacksenterpriseproductioninteractivevisualization

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