Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,6 +5,35 @@ import plotly.express as px
|
|
| 5 |
# Title of the App
|
| 6 |
st.title('Sales Data Visualization App')
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
# Upload File
|
| 9 |
uploaded_file = st.file_uploader("Upload your Excel file", type=["xlsx"])
|
| 10 |
|
|
@@ -27,19 +56,13 @@ if uploaded_file:
|
|
| 27 |
# Clean whitespace and ensure consistent case in 'Customer Name' and 'Product Name'
|
| 28 |
df['Customer Name'] = df['Customer Name'].str.strip().str.lower()
|
| 29 |
df['Product Name'] = df['Product Name'].str.strip().str.lower()
|
| 30 |
-
df['City'] = df['City'].str.strip().str.lower()
|
| 31 |
-
df['Country'] = df['Country'].str.strip().str.lower()
|
| 32 |
-
df['State'] = df['State'].str.strip().str.lower()
|
| 33 |
|
| 34 |
# Sidebar Filters
|
| 35 |
st.sidebar.header("Filter Options")
|
| 36 |
|
| 37 |
-
# Text Input for Customer
|
| 38 |
customer_query = st.sidebar.text_input('Enter Customer Name (partial or full):').strip().lower()
|
| 39 |
product_query = st.sidebar.text_input('Enter Product Name (partial or full):').strip().lower()
|
| 40 |
-
city_query = st.sidebar.text_input('Enter City (partial or full):').strip().lower()
|
| 41 |
-
country_query = st.sidebar.text_input('Enter Country (partial or full):').strip().lower()
|
| 42 |
-
state_query = st.sidebar.text_input('Enter State (partial or full):').strip().lower()
|
| 43 |
|
| 44 |
# Date Range Selection
|
| 45 |
start_date = st.sidebar.date_input('Start Date:', df['Date'].min())
|
|
@@ -47,7 +70,7 @@ if uploaded_file:
|
|
| 47 |
|
| 48 |
# Filter Data by Date Range
|
| 49 |
filtered_df = df[
|
| 50 |
-
(df['Date'] >= pd.to_datetime(start_date)) &
|
| 51 |
(df['Date'] <= pd.to_datetime(end_date))
|
| 52 |
]
|
| 53 |
|
|
@@ -59,18 +82,6 @@ if uploaded_file:
|
|
| 59 |
if product_query:
|
| 60 |
filtered_df = filtered_df[filtered_df['Product Name'].str.contains(product_query, case=False, na=False)]
|
| 61 |
|
| 62 |
-
# Filter Data by City
|
| 63 |
-
if city_query:
|
| 64 |
-
filtered_df = filtered_df[filtered_df['City'].str.contains(city_query, case=False, na=False)]
|
| 65 |
-
|
| 66 |
-
# Filter Data by Country
|
| 67 |
-
if country_query:
|
| 68 |
-
filtered_df = filtered_df[filtered_df['Country'].str.contains(country_query, case=False, na=False)]
|
| 69 |
-
|
| 70 |
-
# Filter Data by State
|
| 71 |
-
if state_query:
|
| 72 |
-
filtered_df = filtered_df[filtered_df['State'].str.contains(state_query, case=False, na=False)]
|
| 73 |
-
|
| 74 |
# Display Filtered Data
|
| 75 |
st.write(f"Filtered Data: {len(filtered_df)} records found.")
|
| 76 |
st.dataframe(filtered_df)
|
|
@@ -87,25 +98,15 @@ if uploaded_file:
|
|
| 87 |
fig_top_products = px.bar(top_products, x='Product Name', y='Net Sales Value', title='Top 10 Products')
|
| 88 |
st.plotly_chart(fig_top_products)
|
| 89 |
|
| 90 |
-
st.subheader("Sales Distribution by
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
st.plotly_chart(
|
| 94 |
-
|
| 95 |
-
st.subheader("Sales by City")
|
| 96 |
-
city_sales = filtered_df.groupby('City')['Net Sales Value'].sum().reset_index()
|
| 97 |
-
fig_city = px.bar(city_sales, x='City', y='Net Sales Value', title='Sales by City')
|
| 98 |
-
st.plotly_chart(fig_city)
|
| 99 |
|
| 100 |
st.subheader("Monthly Sales Heatmap")
|
| 101 |
heatmap_data = filtered_df.pivot_table(values='Net Sales Value', index='Month', columns='Year', aggfunc='sum')
|
| 102 |
fig_heatmap = px.imshow(heatmap_data, labels=dict(x="Year", y="Month", color="Sales"))
|
| 103 |
st.plotly_chart(fig_heatmap)
|
| 104 |
-
|
| 105 |
-
st.subheader("Margin vs. Cost")
|
| 106 |
-
margin_cost = filtered_df.groupby('Product Name')[['Margin Amount', 'Cost']].sum().reset_index()
|
| 107 |
-
fig_margin_cost = px.scatter(margin_cost, x='Cost', y='Margin Amount', color='Product Name', title='Margin vs. Cost')
|
| 108 |
-
st.plotly_chart(fig_margin_cost)
|
| 109 |
else:
|
| 110 |
st.write("No data available for the selected filters.")
|
| 111 |
else:
|
|
|
|
| 5 |
# Title of the App
|
| 6 |
st.title('Sales Data Visualization App')
|
| 7 |
|
| 8 |
+
# Display Sample Data Format
|
| 9 |
+
st.subheader('Sample Data Format:')
|
| 10 |
+
st.write("""
|
| 11 |
+
The data should be in the following format with the listed columns:
|
| 12 |
+
|
| 13 |
+
| Customer Name | Date | City | Country | State | Product Name | Product Attribute 1 | Product Attribute 2 | Product Attribute 3 | Product Attribute 4 | Net Sales Value | Margin Amount | Cost |
|
| 14 |
+
|----------------|------------|--------------|-------------|-------------|-----------------|---------------------|---------------------|---------------------|---------------------|------------------|---------------|-------|
|
| 15 |
+
| John Doe | 2024-01-01 | New York | USA | NY | Product A | Attribute 1A | Attribute 2A | Attribute 3A | Attribute 4A | 1000 | 300 | 700 |
|
| 16 |
+
| Jane Smith | 2024-01-02 | Los Angeles | USA | CA | Product B | Attribute 1B | Attribute 2B | Attribute 3B | Attribute 4B | 1500 | 400 | 1100 |
|
| 17 |
+
| Bob Johnson | 2024-02-15 | Chicago | USA | IL | Product A | Attribute 1A | Attribute 2A | Attribute 3A | Attribute 4A | 1200 | 350 | 850 |
|
| 18 |
+
| Alice Williams | 2024-03-10 | Miami | USA | FL | Product C | Attribute 1C | Attribute 2C | Attribute 3C | Attribute 4C | 2000 | 500 | 1500 |
|
| 19 |
+
| Charlie Brown | 2024-04-05 | Houston | USA | TX | Product B | Attribute 1B | Attribute 2B | Attribute 3B | Attribute 4B | 1800 | 450 | 1350 |
|
| 20 |
+
|
| 21 |
+
### Description of Columns:
|
| 22 |
+
- **Customer Name**: The name of the customer (e.g., John Doe).
|
| 23 |
+
- **Date**: The date of the sale, formatted as `YYYY-MM-DD` (e.g., `2024-01-01`).
|
| 24 |
+
- **City**: The city where the sale took place (e.g., New York).
|
| 25 |
+
- **Country**: The country where the sale took place (e.g., USA).
|
| 26 |
+
- **State**: The state where the sale took place (e.g., NY).
|
| 27 |
+
- **Product Name**: The name of the product (e.g., Product A).
|
| 28 |
+
- **Product Attribute 1**: Additional product attribute (e.g., Attribute 1A).
|
| 29 |
+
- **Product Attribute 2**: Additional product attribute (e.g., Attribute 2A).
|
| 30 |
+
- **Product Attribute 3**: Additional product attribute (e.g., Attribute 3A).
|
| 31 |
+
- **Product Attribute 4**: Additional product attribute (e.g., Attribute 4A).
|
| 32 |
+
- **Net Sales Value**: The net sales value for the transaction (e.g., `1000`).
|
| 33 |
+
- **Margin Amount**: The margin for the transaction (e.g., `300`).
|
| 34 |
+
- **Cost**: The cost of the product sold (e.g., `700`).
|
| 35 |
+
""")
|
| 36 |
+
|
| 37 |
# Upload File
|
| 38 |
uploaded_file = st.file_uploader("Upload your Excel file", type=["xlsx"])
|
| 39 |
|
|
|
|
| 56 |
# Clean whitespace and ensure consistent case in 'Customer Name' and 'Product Name'
|
| 57 |
df['Customer Name'] = df['Customer Name'].str.strip().str.lower()
|
| 58 |
df['Product Name'] = df['Product Name'].str.strip().str.lower()
|
|
|
|
|
|
|
|
|
|
| 59 |
|
| 60 |
# Sidebar Filters
|
| 61 |
st.sidebar.header("Filter Options")
|
| 62 |
|
| 63 |
+
# Text Input for Customer and Product
|
| 64 |
customer_query = st.sidebar.text_input('Enter Customer Name (partial or full):').strip().lower()
|
| 65 |
product_query = st.sidebar.text_input('Enter Product Name (partial or full):').strip().lower()
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
# Date Range Selection
|
| 68 |
start_date = st.sidebar.date_input('Start Date:', df['Date'].min())
|
|
|
|
| 70 |
|
| 71 |
# Filter Data by Date Range
|
| 72 |
filtered_df = df[
|
| 73 |
+
(df['Date'] >= pd.to_datetime(start_date)) &
|
| 74 |
(df['Date'] <= pd.to_datetime(end_date))
|
| 75 |
]
|
| 76 |
|
|
|
|
| 82 |
if product_query:
|
| 83 |
filtered_df = filtered_df[filtered_df['Product Name'].str.contains(product_query, case=False, na=False)]
|
| 84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
# Display Filtered Data
|
| 86 |
st.write(f"Filtered Data: {len(filtered_df)} records found.")
|
| 87 |
st.dataframe(filtered_df)
|
|
|
|
| 98 |
fig_top_products = px.bar(top_products, x='Product Name', y='Net Sales Value', title='Top 10 Products')
|
| 99 |
st.plotly_chart(fig_top_products)
|
| 100 |
|
| 101 |
+
st.subheader("Sales Distribution by Region")
|
| 102 |
+
region_sales = filtered_df.groupby('City')['Net Sales Value'].sum().reset_index()
|
| 103 |
+
fig_region = px.pie(region_sales, names='City', values='Net Sales Value', title='Sales by City')
|
| 104 |
+
st.plotly_chart(fig_region)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
st.subheader("Monthly Sales Heatmap")
|
| 107 |
heatmap_data = filtered_df.pivot_table(values='Net Sales Value', index='Month', columns='Year', aggfunc='sum')
|
| 108 |
fig_heatmap = px.imshow(heatmap_data, labels=dict(x="Year", y="Month", color="Sales"))
|
| 109 |
st.plotly_chart(fig_heatmap)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
else:
|
| 111 |
st.write("No data available for the selected filters.")
|
| 112 |
else:
|