ProtonDataLabs commited on
Commit
8776749
1 Parent(s): 3065b7d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -7
app.py CHANGED
@@ -11,7 +11,30 @@ from datetime import datetime, timedelta
11
  import warnings
12
  import time
13
  import dask.dataframe as dd
14
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  @st.cache_data
16
  def date_from_week(year, week):
17
  # Assuming the fiscal year starts in August and the week starts from August 1st
@@ -29,6 +52,7 @@ def load_data(active_card):
29
  card_specific_cols = {
30
  'card1': ['FyWeek', 'State', 'Itemtype', 'Chaincode', 'SalesVolume'],
31
  'card2': ['FyWeek', 'Fy', 'State','Store','Address','Zipcode','City','Itemtype', 'Chaincode', 'Containercode', 'SalesVolume', 'UnitPrice', 'Sales'],
 
32
  }
33
 
34
  # Choose columns based on the active card
@@ -57,7 +81,7 @@ def load_data(active_card):
57
  df = ddf.compute()
58
 
59
 
60
- if active_card in ['card2']:
61
  df = df.groupby(['FyWeek', 'Fy', 'Chaincode', 'Store', 'Address', 'Zipcode', 'City', 'State', 'Containercode', 'Itemtype'], observed=True).agg({
62
  'SalesVolume': 'sum',
63
  'UnitPrice': 'mean',
@@ -68,6 +92,9 @@ def load_data(active_card):
68
  df['Year'] = df['FY'].str[2:].astype(int) # Extract year part and convert to int
69
  df['Dt'] = date_from_week(df['Year'], df['Week'])
70
 
 
 
 
71
  # st.write(df.columns)
72
  return df
73
 
@@ -75,10 +102,9 @@ def load_data(active_card):
75
  st.image("bonnie.png", width=150) # Adjust width as needed
76
 
77
  # Display title
78
- st.title("Bonnie Plants Pricing & Sales Analytics Dashboard")
 
79
 
80
- # Close the div for logo and title
81
- st.markdown('</div>', unsafe_allow_html=True)
82
 
83
  # Initialize session state for storing which card was clicked and item type
84
  if 'active_card' not in st.session_state:
@@ -90,7 +116,7 @@ if 'selected_feature' not in st.session_state:
90
  st.session_state['selected_feature'] = 'Chaincode' # Default to 'Chain Code'
91
 
92
  # Card selection buttons
93
- col1, col2 = st.columns(2)
94
  # Define buttons for plot categories, update session state when clicked
95
  with col1:
96
  if st.button("Sales Volume Trend for Item Category"):
@@ -99,7 +125,10 @@ with col1:
99
  with col2:
100
  if st.button("Sales Volume & Unit Price Correlation for Item Category and Container Code"):
101
  st.session_state['active_card'] = 'card2'
102
-
 
 
 
103
  start_time=time.time()
104
  # st.write(st.session_state['active_card'])
105
  df = load_data(st.session_state['active_card'])
@@ -246,3 +275,58 @@ if st.session_state['active_card'] == 'card2':
246
 
247
 
248
  ##########################################################################################################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  import warnings
12
  import time
13
  import dask.dataframe as dd
14
+ state_to_region = {
15
+ # WEST
16
+ 'AK': 'WEST', 'CA': 'WEST', 'CO': 'WEST', 'HI': 'WEST', 'ID': 'WEST',
17
+ 'MT': 'WEST', 'NV': 'WEST', 'OR': 'WEST', 'UT': 'WEST', 'WA': 'WEST', 'WY': 'WEST',
18
+
19
+ # SOUTHWEST
20
+ 'AZ': 'SOUTHWEST', 'NM': 'SOUTHWEST', 'OK': 'SOUTHWEST', 'TX': 'SOUTHWEST',
21
+
22
+ # MIDWEST
23
+ 'IL': 'MIDWEST', 'IN': 'MIDWEST', 'IA': 'MIDWEST', 'KS': 'MIDWEST', 'MI': 'MIDWEST',
24
+ 'MN': 'MIDWEST', 'MO': 'MIDWEST', 'NE': 'MIDWEST', 'ND': 'MIDWEST', 'OH': 'MIDWEST',
25
+ 'SD': 'MIDWEST', 'WI': 'MIDWEST',
26
+
27
+ # SOUTHEAST
28
+ 'AL': 'SOUTHEAST', 'AR': 'SOUTHEAST', 'DE': 'SOUTHEAST', 'FL': 'SOUTHEAST',
29
+ 'GA': 'SOUTHEAST', 'KY': 'SOUTHEAST', 'LA': 'SOUTHEAST', 'MD': 'SOUTHEAST',
30
+ 'MS': 'SOUTHEAST', 'NC': 'SOUTHEAST', 'SC': 'SOUTHEAST', 'TN': 'SOUTHEAST',
31
+ 'VA': 'SOUTHEAST', 'WV': 'SOUTHEAST',
32
+
33
+ # NORTHEAST
34
+ 'CT': 'NORTHEAST', 'ME': 'NORTHEAST', 'MA': 'NORTHEAST', 'NH': 'NORTHEAST',
35
+ 'NJ': 'NORTHEAST', 'NY': 'NORTHEAST', 'PA': 'NORTHEAST', 'RI': 'NORTHEAST',
36
+ 'VT': 'NORTHEAST'
37
+ }
38
  @st.cache_data
39
  def date_from_week(year, week):
40
  # Assuming the fiscal year starts in August and the week starts from August 1st
 
52
  card_specific_cols = {
53
  'card1': ['FyWeek', 'State', 'Itemtype', 'Chaincode', 'SalesVolume'],
54
  'card2': ['FyWeek', 'Fy', 'State','Store','Address','Zipcode','City','Itemtype', 'Chaincode', 'Containercode', 'SalesVolume', 'UnitPrice', 'Sales'],
55
+ 'card3': ['FyWeek', 'Fy', 'State', 'Store', 'Itemtype', 'Chaincode', 'SalesVolume', 'UnitPrice', 'Sales'] # Added for PE calculation card
56
  }
57
 
58
  # Choose columns based on the active card
 
81
  df = ddf.compute()
82
 
83
 
84
+ if active_card in ['card2','card3']:
85
  df = df.groupby(['FyWeek', 'Fy', 'Chaincode', 'Store', 'Address', 'Zipcode', 'City', 'State', 'Containercode', 'Itemtype'], observed=True).agg({
86
  'SalesVolume': 'sum',
87
  'UnitPrice': 'mean',
 
92
  df['Year'] = df['FY'].str[2:].astype(int) # Extract year part and convert to int
93
  df['Dt'] = date_from_week(df['Year'], df['Week'])
94
 
95
+ # Add the region column based on state
96
+ df['Region'] = df['State'].map(state_to_region)
97
+
98
  # st.write(df.columns)
99
  return df
100
 
 
102
  st.image("bonnie.png", width=150) # Adjust width as needed
103
 
104
  # Display title
105
+ # st.title("Bonnie Plants Pricing & Sales Analytics Dashboard")
106
+ st.title("Price vs. Sales Volume Tracker Dashboard")
107
 
 
 
108
 
109
  # Initialize session state for storing which card was clicked and item type
110
  if 'active_card' not in st.session_state:
 
116
  st.session_state['selected_feature'] = 'Chaincode' # Default to 'Chain Code'
117
 
118
  # Card selection buttons
119
+ col1, col2 ,col3= st.columns(3)
120
  # Define buttons for plot categories, update session state when clicked
121
  with col1:
122
  if st.button("Sales Volume Trend for Item Category"):
 
125
  with col2:
126
  if st.button("Sales Volume & Unit Price Correlation for Item Category and Container Code"):
127
  st.session_state['active_card'] = 'card2'
128
+ with col3:
129
+ if st.button("PE Coefficient Calculation for Regions & Item Categories"):
130
+ st.session_state['active_card'] = 'card3'
131
+
132
  start_time=time.time()
133
  # st.write(st.session_state['active_card'])
134
  df = load_data(st.session_state['active_card'])
 
275
 
276
 
277
  ##########################################################################################################
278
+
279
+ if st.session_state['active_card'] == 'card3':
280
+ # Dropdown for selecting the item type
281
+ item_type_options = df['Itemtype'].unique()
282
+ selected_item_type = st.selectbox("Select Item Type", item_type_options)
283
+
284
+ # Dropdown for selecting the region (multiple selection allowed)
285
+ region_options = df['Region'].unique()
286
+ selected_regions = st.multiselect("Select Region(s)", region_options, default=region_options)
287
+
288
+ # Filter data based on selected item type and selected regions
289
+ filtered_df = df[(df['Itemtype'] == selected_item_type) & (df['Region'].isin(selected_regions))]
290
+
291
+ # Group by Year, Region, Itemtype and Promo, and aggregate SalesVolume and UnitPrice
292
+ agg_df = filtered_df.groupby(['Fy', 'Region', 'Itemtype',]).agg({
293
+ 'SalesVolume': 'sum',
294
+ 'UnitPrice': 'mean'
295
+ }).reset_index()
296
+
297
+ # Sort values by Region, Itemtype, Fy, and Promo for YOY calculation
298
+ agg_df = agg_df.sort_values(by=['Region', 'Itemtype', 'Fy',])
299
+
300
+ # Calculate YOY percentage changes in Sales Volume and Unit Price
301
+ agg_df['SalesVolume_pct_change'] = agg_df.groupby(['Region', 'Itemtype',])['SalesVolume'].pct_change().round(3) * 100
302
+ agg_df['UnitPrice_pct_change'] = agg_df.groupby(['Region', 'Itemtype', ])['UnitPrice'].pct_change().round(3) * 100
303
+
304
+ # Calculate Price Elasticity Coefficient (PE)
305
+ agg_df['PE_Coeff'] = (agg_df['SalesVolume_pct_change'] / agg_df['UnitPrice_pct_change']).round(2)
306
+
307
+ # Exclude FY 2025 but keep FY 2021 even with NaN values
308
+ agg_df_filtered = agg_df[agg_df['Fy'] != 'FY 2025']
309
+
310
+ # Drop rows where PE_Coeff is NaN (optional)
311
+ agg_df_filtered = agg_df_filtered.dropna(subset=['PE_Coeff'])
312
+ st.dataframe(agg_df_filtered)
313
+ st.write(agg_df_filtered.shape)
314
+ # Plot the PE Coefficient with Plotly
315
+ fig = px.line(
316
+ agg_df_filtered,
317
+ x='Fy',
318
+ y='PE_Coeff', # Differentiate between Promo and NoPromo
319
+ line_dash='Region', # Differentiate lines by Region
320
+ title=f"Price Elasticity Coefficient (PE) by Year for {selected_item_type}",
321
+ labels={'Fy': 'Fiscal Year', 'PE_Coeff': 'Price Elasticity Coefficient'},
322
+ markers=True
323
+ )
324
+
325
+ # Customize layout and show plot
326
+ fig.update_layout(
327
+ height=600,
328
+ width=1000,
329
+ )
330
+
331
+ st.plotly_chart(fig, use_container_width=True)
332
+ ###################################################################################################################