Have you ever created a data analysis in Python, generated some charts, and then realized that the only way to show the results was by sending screenshots or a Jupyter Notebook?
For data analysts and developers, visualizing information is only part of the challenge. A good data project should also be interactive, accessible, reproducible, and easy to deploy.
This is where Streamlit becomes extremely useful.
Streamlit is a Python framework that allows developers to transform Python scripts into interactive web applications without needing to build a separate frontend using HTML, CSS, or JavaScript.
In this article, we will build a Sales Analytics Dashboard using Python, Pandas, Plotly, and Streamlit. We will then publish the source code on GitHub, implement automation with GitHub Actions, and deploy the application publicly using Streamlit Community Cloud.
📊 The Project: Sales Analytics Dashboard
Imagine that a company wants to analyze its sales performance.
The company needs a dashboard where users can quickly see:
- Total revenue
- Total orders
- Average order value
- Revenue by product category
- Monthly sales trends
- Sales by region
Instead of generating static charts, we will create an interactive dashboard where users can filter the information and see the visualizations update automatically.
Our technology stack will be:
- Python – Programming language
- Pandas – Data processing
- Plotly – Interactive charts
- Streamlit – Dashboard interface
- GitHub – Version control and public repository
- GitHub Actions – Automation and validation
- Streamlit Community Cloud – Public deployment
Step 1: Project Structure
Before writing the dashboard, we organize the project.
sales-dashboard/
│
├── .github/
│ └── workflows/
│ └── python-app.yml
│
├── data/
│ └── sales.csv
│
├── app.py
├── requirements.txt
└── README.md
The most important file is app.py, which contains our Streamlit application.
The requirements.txt file contains all Python dependencies required to run the project.
Our requirements.txt looks like this:
streamlit
pandas
plotly
Step 2: Creating the Dataset
For this example, imagine that our sales.csv file contains the following information:
Date,Product,Category,Region,Quantity,Revenue
2026-01-05,Laptop,Technology,North,2,2400
2026-01-10,Headphones,Technology,South,5,750
2026-02-03,Office Chair,Furniture,West,3,900
2026-02-15,Desk,Furniture,East,2,1200
2026-03-01,Smartphone,Technology,North,4,3200
2026-03-20,Notebook,Office Supplies,South,20,200
2026-04-10,Monitor,Technology,West,3,1050
2026-04-22,Printer,Office Supplies,East,2,700
In a real-world project, this dataset could come from a database, API, Excel file, cloud storage service, or business information system.
For this dashboard, we will load the CSV file using Pandas.
Step 3: Building the Streamlit Application
Now we can create the main application.
Create a file named:
app.py
First, import the required libraries:
import streamlit as st
import pandas as pd
import plotly.express as px
Next, configure the Streamlit page:
st.set_page_config(
page_title="Sales Analytics Dashboard",
page_icon="📊",
layout="wide"
)
st.title("📊 Sales Analytics Dashboard")
st.write(
"Interactive dashboard for analyzing sales performance "
"by category, region and time."
)
The layout="wide" configuration gives us more horizontal space, which is particularly useful for dashboards.
Step 4: Loading and Preparing the Data
We can load our dataset with Pandas:
@st.cache_data
def load_data():
df = pd.read_csv("data/sales.csv")
df["Date"] = pd.to_datetime(df["Date"])
return df
df = load_data()
The dataset contains sales transactions with information such as date, category, region, quantity, and revenue.
After converting the Date column into a datetime value, we can also create a month field:
df["Month"] = df["Date"].dt.to_period("M").astype(str)
This will allow us to analyze monthly sales trends.
Step 5: Adding Interactive Filters
One of the main advantages of Streamlit is that we can easily add interactive widgets.
For example, users can filter the dashboard by region and product category.
st.sidebar.header("Dashboard Filters")
selected_region = st.sidebar.multiselect(
"Select Region",
options=df["Region"].unique(),
default=df["Region"].unique()
)
selected_category = st.sidebar.multiselect(
"Select Category",
options=df["Category"].unique(),
default=df["Category"].unique()
)
Now we apply these filters to our dataset:
filtered_df = df[
(df["Region"].isin(selected_region)) &
(df["Category"].isin(selected_category))
]
Every visualization that uses filtered_df will automatically update when the user changes the filters.
Step 6: Creating KPI Metrics
A dashboard should provide important information immediately.
For this project, we will calculate three Key Performance Indicators:
- Total Revenue
- Total Orders
- Average Order Value
total_revenue = filtered_df["Revenue"].sum()
total_orders = len(filtered_df)
average_order_value = (
total_revenue / total_orders
if total_orders > 0
else 0
)
Then we display them using Streamlit metrics:
col1, col2, col3 = st.columns(3)
col1.metric(
"💰 Total Revenue",
f"${total_revenue:,.2f}"
)
col2.metric(
"🛒 Total Orders",
total_orders
)
col3.metric(
"📈 Average Order Value",
f"${average_order_value:,.2f}"
)
This gives users a quick summary of the current filtered data.
Step 7: Revenue by Category
Now we can create our first visualization.
We group the data by product category:
category_sales = (
filtered_df.groupby("Category")["Revenue"]
.sum()
.reset_index()
)
Then we create an interactive bar chart using Plotly:
fig_category = px.bar(
category_sales,
x="Category",
y="Revenue",
title="Revenue by Product Category",
text_auto=True
)
st.plotly_chart(
fig_category,
use_container_width=True
)
Users can interact with the Plotly visualization by hovering over bars, zooming, and inspecting individual values.
Step 8: Monthly Sales Trend
Another important business visualization is the evolution of revenue over time.
First, we calculate monthly revenue:
monthly_sales = (
filtered_df.groupby("Month")["Revenue"]
.sum()
.reset_index()
)
Then we generate a line chart:
fig_month = px.line(
monthly_sales,
x="Month",
y="Revenue",
markers=True,
title="Monthly Revenue Trend"
)
st.plotly_chart(
fig_month,
use_container_width=True
)
This chart helps identify sales growth, reductions, or unusual changes over time.
Step 9: Sales by Region
We can also compare revenue between different geographical regions.
region_sales = (
filtered_df.groupby("Region")["Revenue"]
.sum()
.reset_index()
)
For this visualization, we can use a pie chart:
fig_region = px.pie(
region_sales,
names="Region",
values="Revenue",
title="Revenue Distribution by Region"
)
st.plotly_chart(
fig_region,
use_container_width=True
)
Our dashboard now contains multiple visualization techniques for understanding the same dataset from different perspectives.
Step 10: Displaying the Raw Data
Sometimes users need to inspect the original information.
At the bottom of the application, we can include an expandable section containing the filtered dataset.
with st.expander("View Dataset"):
st.dataframe(
filtered_df,
use_container_width=True
)
This allows the dashboard to work both as a visualization tool and a simple data exploration interface.
🧩 Complete Application
The final app.py file looks like this:
import streamlit as st
import pandas as pd
import plotly.express as px
st.set_page_config(
page_title="Sales Analytics Dashboard",
page_icon="📊",
layout="wide"
)
st.title("📊 Sales Analytics Dashboard")
st.write(
"Interactive dashboard for analyzing sales performance "
"by category, region and time."
)
@st.cache_data
def load_data():
df = pd.read_csv("data/sales.csv")
df["Date"] = pd.to_datetime(df["Date"])
df["Month"] = df["Date"].dt.to_period("M").astype(str)
return df
df = load_data()
# Sidebar filters
st.sidebar.header("Dashboard Filters")
selected_region = st.sidebar.multiselect(
"Select Region",
options=df["Region"].unique(),
default=df["Region"].unique()
)
selected_category = st.sidebar.multiselect(
"Select Category",
options=df["Category"].unique(),
default=df["Category"].unique()
)
filtered_df = df[
(df["Region"].isin(selected_region)) &
(df["Category"].isin(selected_category))
]
# KPIs
total_revenue = filtered_df["Revenue"].sum()
total_orders = len(filtered_df)
average_order_value = (
total_revenue / total_orders
if total_orders > 0
else 0
)
col1, col2, col3 = st.columns(3)
col1.metric(
"💰 Total Revenue",
f"${total_revenue:,.2f}"
)
col2.metric(
"🛒 Total Orders",
total_orders
)
col3.metric(
"📈 Average Order Value",
f"${average_order_value:,.2f}"
)
# Revenue by Category
category_sales = (
filtered_df.groupby("Category")["Revenue"]
.sum()
.reset_index()
)
fig_category = px.bar(
category_sales,
x="Category",
y="Revenue",
title="Revenue by Product Category",
text_auto=True
)
st.plotly_chart(
fig_category,
use_container_width=True
)
# Monthly Revenue
monthly_sales = (
filtered_df.groupby("Month")["Revenue"]
.sum()
.reset_index()
)
fig_month = px.line(
monthly_sales,
x="Month",
y="Revenue",
markers=True,
title="Monthly Revenue Trend"
)
st.plotly_chart(
fig_month,
use_container_width=True
)
# Revenue by Region
region_sales = (
filtered_df.groupby("Region")["Revenue"]
.sum()
.reset_index()
)
fig_region = px.pie(
region_sales,
names="Region",
values="Revenue",
title="Revenue Distribution by Region"
)
st.plotly_chart(
fig_region,
use_container_width=True
)
# Dataset
with st.expander("View Dataset"):
st.dataframe(
filtered_df,
use_container_width=True
)
Running the application locally is extremely simple:
streamlit run app.py
After executing the command, Streamlit starts a local web server where we can test and interact with the dashboard.
Step 11: Publishing the Project on GitHub
A public repository is important because it allows other developers to inspect, reproduce, and improve the project.
After creating a new GitHub repository, we can upload the project using Git:
git init
git add .
git commit -m "Initial Streamlit dashboard"
git branch -M main
git remote add origin https://github.com/YOUR-USERNAME/sales-dashboard.git
git push -u origin main
Step 12: Automation with GitHub Actions
Publishing code is not enough.
We also want an automated process that verifies that the application can be installed and that the Python code is valid whenever changes are pushed to the repository.
For this purpose, we can use GitHub Actions.
Create the following file:
.github/workflows/python-app.yml
Add:
name: Streamlit Dashboard CI
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
test-dashboard:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Check Python syntax
run: |
python -m py_compile app.py
Now every push or Pull Request to the main branch automatically executes the workflow.
The workflow performs three important tasks:
- Downloads the repository.
- Creates the Python environment and installs the dependencies.
- Checks that the application does not contain Python syntax errors.
If something is wrong, GitHub Actions marks the workflow as failed.
This provides a simple Continuous Integration (CI) process for our dashboard.
Step 13: Deploying to Streamlit Community Cloud
Now comes the most important part: making the dashboard publicly accessible.
Streamlit Community Cloud can deploy Streamlit applications directly from GitHub.
The deployment process is:
- Push the complete application to GitHub.
- Sign in to Streamlit Community Cloud.
- Connect the GitHub account.
- Select the dashboard repository.
- Select the
mainbranch. - Specify
app.pyas the application entry point. - Deploy the application.
The platform installs the dependencies contained in requirements.txt and starts the Streamlit application.
Once deployed, the dashboard receives a public address similar to:
https://your-dashboard.streamlit.app
Step 14: Continuous Deployment
Our development workflow now becomes:
Developer
↓
Git Push
↓
GitHub Repository
↓
GitHub Actions
↓
Validation
↓
Streamlit Community Cloud
↓
Public Dashboard
GitHub acts as the source of truth for the application.
When we update the project and push the changes to GitHub, our automated GitHub Actions workflow validates the application.
The deployed Streamlit application can then reflect the new version stored in the repository.
This approach gives us a simple CI/CD workflow without needing to manually upload application files every time we make a change.
Conclusion
Building a dashboard is not only about creating charts.
A complete modern data project also involves version control, automation, deployment, and accessibility.
Using Pandas and Plotly, we transformed raw sales information into meaningful visualizations. Streamlit allowed us to transform those visualizations into an interactive web application without developing a traditional frontend.
GitHub provided version control and a public repository, while GitHub Actions added automated validation to the development process.
Finally, Streamlit Community Cloud allowed us to transform a local Python project into a publicly accessible web application.
The complete workflow demonstrates how modern development and data visualization tools can work together:
Data → Analysis → Visualization → Application → Automation → Cloud Deployment
Instead of sharing static screenshots or notebooks, we now have a real interactive dashboard that anyone can access from a browser.
Top comments (0)