Streamlit makes it remarkably fast to transform raw Python scripts into interactive, web-based data applications without needing any frontend knowledge in HTML, CSS, or JavaScript.
In this tutorial, we will build a full-featured **Sales Analytics Dashboard** complete with real-time sidebar filtering, custom KPI metric cards, dynamic line/bar charts, and expandable data preview tables.
---
## Prerequisites
To follow along, make sure you have Python 3.9+ installed along with the required libraries:
bash
pip install streamlit pandas numpy
---
## Step 1: Setting Up the Page & Mock Data with Caching
First, we import the necessary libraries, set up the layout, and create a function to generate mock sales records.
We use Streamlit’s `@st.cache_data` decorator so the data is only generated once per session, keeping the app snappy during user interactions.
python
import streamlit as st
import pandas as pd
import numpy as np
Set layout configuration
st.set_page_config(page_title="Sales Dashboard", layout="wide")
Cache data loading for performance optimization
@st.cache_data
def load_data():
dates = pd.date_range("2025-01-01", periods=180)
regions = ["North", "South", "East", "West"]
df = pd.DataFrame({
"date": np.random.choice(dates, 500),
"region": np.random.choice(regions, 500),
"product": np.random.choice(["A", "B", "C"], 500),
"sales": np.random.randint(100, 5000, 500),
"units": np.random.randint(1, 50, 500),
})
return df.sort_values("date")
df = load_data()
---
## Step 2: Adding Interactive Sidebar Filters
Next, we add controls inside the sidebar to let users filter the dataset by region, product type, and date range. A boolean mask applies those selections dynamically.
python
--- Sidebar filters ---
st.sidebar.header("Filters")
region_filter = st.sidebar.multiselect("Region", df["region"].unique(), default=df["region"].unique())
product_filter = st.sidebar.multiselect("Product", df["product"].unique(), default=df["product"].unique())
date_range = st.sidebar.date_input("Date range", [df["date"].min(), df["date"].max()])
Filter dataframe based on selections
mask = (
df["region"].isin(region_filter)
& df["product"].isin(product_filter)
& (df["date"] >= pd.to_datetime(date_range[0]))
& (df["date"] <= pd.to_datetime(date_range[1]))
)
filtered = df[mask]
---
## Step 3: Displaying High-Level KPI Metrics
To display top-level executive metrics at a glance, we split the main body into 4 equal columns using `st.columns()` and populate them with `st.metric()`.
python
--- Title & Subtitle ---
st.title("📈 Sales Dashboard")
st.caption(f"Showing {len(filtered):,} records")
--- KPI row ---
c1, c2, c3, c4 = st.columns(4)
c1.metric("Total Sales", f"${filtered['sales'].sum():,.0f}")
c2.metric("Total Units", f"{filtered['units'].sum():,}")
c3.metric("Avg Order", f"${filtered['sales'].mean():,.0f}" if len(filtered) else "$0")
c4.metric("Orders", f"{len(filtered):,}")
st.divider()
---
## Step 4: Adding Charts & Raw Data Views
Finally, we group the filtered data and visualize trends using Streamlit's built-in `line_chart` and `bar_chart` components. We also wrap the raw DataFrame inside an expandable container (`st.expander`) to keep the interface clean.
python
--- Visualizations ---
col1, col2 = st.columns(2)
with col1:
st.subheader("Sales Over Time")
daily = filtered.groupby("date")["sales"].sum()
st.line_chart(daily)
with col2:
st.subheader("Sales by Region")
by_region = filtered.groupby("region")["sales"].sum()
st.bar_chart(by_region)
--- Product Performance ---
st.subheader("Sales by Product")
by_product = filtered.groupby("product")["sales"].sum()
st.bar_chart(by_product)
--- Raw Data Section ---
with st.expander("View raw data"):
st.dataframe(filtered, use_container_width=True)
---
## Running the Application
Save your Python code in a file named `app.py` and run the following command in your terminal:
bash
streamlit run app.py
Your browser will automatically open a tab at `http://localhost:8501` showing your live interactive sales dashboard.
---
## Conclusion
With less than 80 lines of clean Python code, we built a responsive dashboard that updates instantaneously as users interact with filters. Streamlit handles the state management, caching, and layout automatically, allowing developers and data engineers to focus purely on the logic and insights.
Top comments (1)
Nice walkthrough. One thing I’d add is that the example scales well for a demo, but production dashboards usually need a few extra considerations.
As datasets grow, repeatedly filtering a pandas DataFrame on every interaction can become the bottleneck. It’s also worth discussing incremental loading, database-backed queries, cache invalidation strategies, and handling empty or invalid filter states gracefully.
I also like to separate the app into layers (data access, business logic, and UI) rather than keeping everything in a single app.py. It makes testing and maintenance much easier as the dashboard evolves.
Overall, it’s a solid introduction that gets people productive quickly, and these production-oriented practices are a natural next step.