ProtonDataLabs commited on
Commit
2830d45
·
unverified ·
1 Parent(s): 1d3a4de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +198 -43
app.py CHANGED
@@ -50,7 +50,7 @@ def load_data(active_card):
50
 
51
  # Columns specific to cards
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','Address','Zipcode','City','Itemtype', 'Chaincode', 'Containercode', 'SalesVolume', 'UnitPrice', 'Sales'] # Added for PE calculation card
56
  }
@@ -82,7 +82,7 @@ def load_data(active_card):
82
 
83
  # st.write("+++++++++++++++++++++++")
84
 
85
- if active_card in ['card2', 'card3', 'card4']:
86
  df = df.groupby(['FyWeek', 'Fy', 'Chaincode', 'Store', 'Address', 'Zipcode', 'City', 'State', 'Containercode', 'Itemtype'], observed=True).agg({
87
  'SalesVolume': 'sum',
88
  'UnitPrice': 'mean',
@@ -96,19 +96,13 @@ def load_data(active_card):
96
  df['Region'] = df['State'].map(state_to_region)
97
 
98
  return df
99
-
100
- # st.image("bonnie.png", width=200)
101
- # # Main interactive section
102
- # st.title('Bonnnie Plants Price vs Sales Volume Trcaker')
103
-
104
  # Display logo
105
  st.image("bonnie.png", width=150) # Adjust width as needed
106
 
107
  # Display title
108
  st.title("Bonnie Plants Pricing & Sales Analytics Dashboard")
109
 
110
- # Close the div for logo and title
111
- # st.markdown('</div>', unsafe_allow_html=True)
112
 
113
  # Initialize session state for storing which card was clicked and item type
114
  if 'active_card' not in st.session_state:
@@ -119,60 +113,221 @@ if 'selected_item_type' not in st.session_state:
119
  if 'selected_feature' not in st.session_state:
120
  st.session_state['selected_feature'] = 'Chaincode' # Default to 'Chain Code'
121
 
122
- # Card selection buttons
123
- col1, col2, col3= st.columns(3)
124
- # Define buttons for plot categories, update session state when clicked
125
  with col1:
126
  if st.button("Sales Volume Trend for Item Category"):
127
  st.session_state['active_card'] = 'card1'
 
 
 
 
 
128
 
129
  with col2:
130
  if st.button("Sales Volume & Unit Price Correlation for Item Category and Container Code"):
131
  st.session_state['active_card'] = 'card2'
 
 
 
 
 
 
132
  with col3:
133
  if st.button("PE Coefficient Calculation for Regions & Item Categories"):
134
  st.session_state['active_card'] = 'card3'
135
-
136
-
137
- start_time=time.time()
138
- # st.write(st.session_state['active_card'])
 
 
 
 
139
  df = load_data(st.session_state['active_card'])
140
  time_taken = time.time() - start_time
141
  st.write(f"Data loaded in {time_taken:.2f} seconds")
142
 
143
 
144
- # Initialize session state for storing the selected state and feature
145
- if 'selected_state' not in st.session_state:
146
- st.session_state['selected_state'] = df['State'].unique()[0] # Default to the first state
147
-
148
  ############################################ CARD #1 ####################################################
149
  if st.session_state['active_card'] == 'card1':
150
- # st.write("Processing card1...")
151
- # Dropdown for selecting the state
152
- selected_state = st.selectbox('Select State', df['State'].unique())
153
- # Dropdown for selecting the feature for grouping
154
- selected_feature = st.selectbox('Select Feature for Grouping', ['Chaincode', 'Itemtype',])
155
-
156
- # Filter the dataframe based on selected state
157
- filtered_df = df[df['State'] == selected_state]
158
-
159
- # Time the grouping operation
160
- start_time = time.time()
161
- group_data = filtered_df.groupby(['FyWeek', selected_feature],observed=True)['SalesVolume'].sum().reset_index()
162
- time_taken = time.time() - start_time
163
- # st.write(f"Data grouped in {time_taken:.2f} seconds")
164
-
165
- # Plotting
166
- fig = px.bar(group_data, x='FyWeek', y='SalesVolume', color=selected_feature,
167
- title=f'Sales Volume over Fiscal Week in {selected_state} by {selected_feature}',
168
- labels={'SalesVolume': 'Sales Volume', 'Fiscal Week Short': 'Fiscal Week'})
169
- st.plotly_chart(fig)
170
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  ##########################################################################################################
172
 
173
- ##########################################################################################################
174
 
 
175
  if st.session_state['active_card'] == 'card2':
 
 
 
 
 
176
  # Dropdown to select item type (using session_state)
177
  st.session_state['selected_item_type'] = st.selectbox(
178
  'Select Item Type', df['Itemtype'].unique(),
@@ -279,7 +434,7 @@ if st.session_state['active_card'] == 'card3':
279
  selected_item_type = st.selectbox("Select Item Type", item_type_options)
280
 
281
  # Dropdown for selecting the region (multiple selection allowed)
282
- region_options = df['Region'].unique()
283
  selected_regions = st.multiselect("Select Region(s)", region_options, default=region_options)
284
 
285
  # Filter data based on selected item type and selected regions
 
50
 
51
  # Columns specific to cards
52
  card_specific_cols = {
53
+ 'card1': ['FyWeek', 'Fy', 'State','Store','Address','Zipcode','City','Itemtype', 'Chaincode', 'Containercode', 'SalesVolume', 'UnitPrice', 'Sales'],
54
  'card2': ['FyWeek', 'Fy', 'State','Store','Address','Zipcode','City','Itemtype', 'Chaincode', 'Containercode', 'SalesVolume', 'UnitPrice', 'Sales'],
55
  'card3': ['FyWeek', 'Fy', 'State','Store','Address','Zipcode','City','Itemtype', 'Chaincode', 'Containercode', 'SalesVolume', 'UnitPrice', 'Sales'] # Added for PE calculation card
56
  }
 
82
 
83
  # st.write("+++++++++++++++++++++++")
84
 
85
+ if active_card in ['card1','card2', 'card3',]:
86
  df = df.groupby(['FyWeek', 'Fy', 'Chaincode', 'Store', 'Address', 'Zipcode', 'City', 'State', 'Containercode', 'Itemtype'], observed=True).agg({
87
  'SalesVolume': 'sum',
88
  'UnitPrice': 'mean',
 
96
  df['Region'] = df['State'].map(state_to_region)
97
 
98
  return df
99
+
 
 
 
 
100
  # Display logo
101
  st.image("bonnie.png", width=150) # Adjust width as needed
102
 
103
  # Display title
104
  st.title("Bonnie Plants Pricing & Sales Analytics Dashboard")
105
 
 
 
106
 
107
  # Initialize session state for storing which card was clicked and item type
108
  if 'active_card' not in st.session_state:
 
113
  if 'selected_feature' not in st.session_state:
114
  st.session_state['selected_feature'] = 'Chaincode' # Default to 'Chain Code'
115
 
116
+ # Card selection buttons with logic to reset session state on switch
117
+ col1, col2, col3 = st.columns(3)
 
118
  with col1:
119
  if st.button("Sales Volume Trend for Item Category"):
120
  st.session_state['active_card'] = 'card1'
121
+ # Reset other selections when switching cards
122
+ st.session_state['selected_state'] = None
123
+ st.session_state['selected_chaincode'] = None
124
+ st.session_state['selected_itemtype'] = None
125
+ st.session_state['selected_containercode'] = None
126
 
127
  with col2:
128
  if st.button("Sales Volume & Unit Price Correlation for Item Category and Container Code"):
129
  st.session_state['active_card'] = 'card2'
130
+ # Reset selections when switching cards
131
+ st.session_state['selected_state'] = None
132
+ st.session_state['selected_chaincode'] = None
133
+ st.session_state['selected_itemtype'] = None
134
+ st.session_state['selected_containercode'] = None
135
+
136
  with col3:
137
  if st.button("PE Coefficient Calculation for Regions & Item Categories"):
138
  st.session_state['active_card'] = 'card3'
139
+ # Reset selections when switching cards
140
+ st.session_state['selected_state'] = None
141
+ st.session_state['selected_chaincode'] = None
142
+ st.session_state['selected_itemtype'] = None
143
+ st.session_state['selected_containercode'] = None
144
+
145
+ # Load data for the current card
146
+ start_time = time.time()
147
  df = load_data(st.session_state['active_card'])
148
  time_taken = time.time() - start_time
149
  st.write(f"Data loaded in {time_taken:.2f} seconds")
150
 
151
 
 
 
 
 
152
  ############################################ CARD #1 ####################################################
153
  if st.session_state['active_card'] == 'card1':
154
+ # Step 1: Sales Volume vs FyWeek for the whole dataset (no filter)
155
+ st.subheader("Total Sales Volume vs Fiscal Week")
156
+ df['FY_Week'] = df['FY'].astype(str) + '_' + df['Week'].astype(str)
157
+ # Split FY_Week again for correct sorting
158
+ if not df.empty and 'FY_Week' in df.columns:
159
+ total_sales_df = df.groupby('FY_Week', observed=True)['SalesVolume'].sum().reset_index()
160
+ total_sales_df[['FY', 'Week']] = total_sales_df['FY_Week'].str.split('_', expand=True)
161
+ total_sales_df['Week'] = total_sales_df['Week'].astype(int)
162
+ total_sales_df = total_sales_df.sort_values(by=['FY', 'Week'])
163
+
164
+ # Create a line chart using Plotly
165
+ fig = px.line(total_sales_df, x='FY_Week', y='SalesVolume',
166
+ title='Total Sales Volume vs Fiscal Week',
167
+ labels={'SalesVolume': 'Sales Volume', 'FY_Week': 'Fiscal Week'})
168
+ st.plotly_chart(fig)
169
+
170
+ # Step 2: Top 3 states based on sales volume as buttons/cards
171
+ top_states = df.groupby('State', observed=True)['SalesVolume'].sum().nlargest(3).index
172
+ st.write("### Top 3 Selling States :")
173
+ col1, col2, col3 = st.columns(3)
174
+ if len(top_states) > 0 and col1.button(top_states[0]):
175
+ st.session_state['selected_state'] = top_states[0]
176
+ if len(top_states) > 1 and col2.button(top_states[1]):
177
+ st.session_state['selected_state'] = top_states[1]
178
+ if len(top_states) > 2 and col3.button(top_states[2]):
179
+ st.session_state['selected_state'] = top_states[2]
180
+
181
+ # If a state is selected, show the corresponding plot
182
+ if 'selected_state' in st.session_state and st.session_state['selected_state']:
183
+ selected_state = st.session_state['selected_state']
184
+
185
+ # Step 3: Sales volume vs FyWeek for the selected state
186
+ st.subheader(f"Sales Volume vs Fiscal Week for {selected_state}")
187
+ state_sales_df = df[df['State'] == selected_state].groupby('FY_Week', observed=True)['SalesVolume'].sum().reset_index()
188
+
189
+ if not state_sales_df.empty and 'FY_Week' in state_sales_df.columns:
190
+ state_sales_df[['FY', 'Week']] = state_sales_df['FY_Week'].str.split('_', expand=True)
191
+ state_sales_df['Week'] = state_sales_df['Week'].astype(int)
192
+ state_sales_df = state_sales_df.sort_values(by=['FY', 'Week'])
193
+
194
+ fig = px.line(state_sales_df, x='FY_Week', y='SalesVolume',
195
+ title=f'Sales Volume vs Fiscal Week in {selected_state}',
196
+ labels={'SalesVolume': 'Sales Volume', 'FY_Week': 'Fiscal Week'})
197
+ st.plotly_chart(fig)
198
+
199
+ # Step 4: Top 3 chaincodes based on sales volume as buttons/cards
200
+ top_chaincodes = df[df['State'] == selected_state].groupby('Chaincode', observed=True)['SalesVolume'].sum().nlargest(3).index
201
+ st.write(f"### Top 3 selling Chaincode in {selected_state}:")
202
+
203
+ # Add a check to ensure top_chaincodes has values before accessing
204
+ col1, col2, col3 = st.columns(3)
205
+ if len(top_chaincodes) > 0 and col1.button(top_chaincodes[0]):
206
+ st.session_state['selected_chaincode'] = top_chaincodes[0]
207
+ if len(top_chaincodes) > 1 and col2.button(top_chaincodes[1]):
208
+ st.session_state['selected_chaincode'] = top_chaincodes[1]
209
+ if len(top_chaincodes) > 2 and col3.button(top_chaincodes[2]):
210
+ st.session_state['selected_chaincode'] = top_chaincodes[2]
211
+
212
+ # If a chaincode is selected, show the corresponding plot
213
+ if 'selected_chaincode' in st.session_state:
214
+ selected_chaincode = st.session_state['selected_chaincode']
215
+
216
+ # Step 5: Sales volume vs FyWeek for the selected chaincode in the selected state
217
+ st.subheader(f"Sales Volume vs Fiscal Week for {selected_chaincode} in {selected_state}")
218
+ chain_sales_df = df[(df['State'] == selected_state) & (df['Chaincode'] == selected_chaincode)].groupby('FY_Week', observed=True)['SalesVolume'].sum().reset_index()
219
+
220
+ if not chain_sales_df.empty and 'FY_Week' in chain_sales_df.columns:
221
+ chain_sales_df[['FY', 'Week']] = chain_sales_df['FY_Week'].str.split('_', expand=True)
222
+ chain_sales_df['Week'] = chain_sales_df['Week'].astype(int)
223
+ chain_sales_df = chain_sales_df.sort_values(by=['FY', 'Week'])
224
+
225
+ fig = px.line(chain_sales_df, x='FY_Week', y='SalesVolume',
226
+ title=f'Sales Volume vs Fiscal Week in {selected_chaincode}, {selected_state}',
227
+ labels={'SalesVolume': 'Sales Volume', 'FY_Week': 'Fiscal Week'})
228
+ st.plotly_chart(fig)
229
+
230
+ # Step 6: Top 3 itemtypes based on sales volume as buttons/cards
231
+ top_itemtypes = df[(df['State'] == selected_state) & (df['Chaincode'] == selected_chaincode)].groupby('Itemtype', observed=True)['SalesVolume'].sum().nlargest(3).index
232
+ st.write(f"### Top Itemtype in {selected_chaincode}, {selected_state}:")
233
+
234
+ col1, col2, col3 = st.columns(3)
235
+ if len(top_itemtypes) > 0 and col1.button(top_itemtypes[0]):
236
+ st.session_state['selected_itemtype'] = top_itemtypes[0]
237
+ if len(top_itemtypes) > 1 and col2.button(top_itemtypes[1]):
238
+ st.session_state['selected_itemtype'] = top_itemtypes[1]
239
+ if len(top_itemtypes) > 2 and col3.button(top_itemtypes[2]):
240
+ st.session_state['selected_itemtype'] = top_itemtypes[2]
241
+
242
+ # If an itemtype is selected, show the corresponding dual-axis plot for Sales Volume & Unit Price
243
+ if 'selected_itemtype' in st.session_state:
244
+ selected_itemtype = st.session_state['selected_itemtype']
245
+
246
+ # Step 7: Dual-axis plot for Sales volume and UnitPrice vs FyWeek for the selected itemtype
247
+ st.subheader(f"Sales Volume & Unit Price vs Fiscal Week for {selected_itemtype} in {selected_chaincode}, {selected_state}")
248
+ item_sales_df = df[(df['State'] == selected_state) & (df['Chaincode'] == selected_chaincode) & (df['Itemtype'] == selected_itemtype)].groupby('FY_Week', observed=True).agg({
249
+ 'SalesVolume': 'sum',
250
+ 'UnitPrice': 'mean'
251
+ }).reset_index()
252
+ if not item_sales_df.empty and 'FY_Week' in item_sales_df.columns:
253
+ item_sales_df[['FY', 'Week']] = item_sales_df['FY_Week'].str.split('_', expand=True)
254
+ item_sales_df['Week'] = item_sales_df['Week'].astype(int)
255
+ item_sales_df = item_sales_df.sort_values(by=['FY', 'Week'])
256
+
257
+ # Dual-axis plot using Plotly Graph Objects
258
+ fig = go.Figure()
259
+
260
+ # Add SalesVolume trace
261
+ fig.add_trace(go.Scatter(
262
+ x=item_sales_df['FY_Week'],
263
+ y=item_sales_df['SalesVolume'],
264
+ mode='lines+markers',
265
+ name='SalesVolume',
266
+ line=dict(color='blue'),
267
+ hovertemplate='SalesVolume: %{y}<br>Week-Year: %{x}'
268
+ ))
269
+
270
+ # Add UnitPrice trace with secondary Y-axis
271
+ fig.add_trace(go.Scatter(
272
+ x=item_sales_df['FY_Week'],
273
+ y=item_sales_df['UnitPrice'],
274
+ mode='lines+markers',
275
+ name='UnitPrice',
276
+ line=dict(color='green'),
277
+ yaxis='y2',
278
+ hovertemplate='UnitPrice: %{y}<br>Week-Year: %{x}'
279
+ ))
280
+
281
+ # Update layout for dual axes
282
+ fig.update_layout(
283
+ title=f"Sales Volume & Unit Price vs Fiscal Week in {selected_itemtype}, {selected_chaincode}, {selected_state}",
284
+ xaxis_title='Fiscal Week',
285
+ yaxis_title='Sales Volume',
286
+ yaxis2=dict(title='Unit Price', overlaying='y', side='right'),
287
+ legend=dict(x=0.9, y=1.15),
288
+ hovermode="x unified", # Show both values in a tooltip
289
+ height=600,
290
+ margin=dict(l=50, r=50, t=50, b=50)
291
+ )
292
+
293
+ # Rotate X-axis labels
294
+ fig.update_xaxes(tickangle=90)
295
+
296
+ # Display the Plotly figure in Streamlit
297
+ st.plotly_chart(fig, use_container_width=True)
298
+ # Step 8: Display Top/Bottom Container Codes and Stores
299
+ st.subheader("Top & Bottom 3 Container Codes and Stores")
300
+
301
+ # Get top and bottom 3 container codes based on SalesVolume
302
+ top_containercodes = df[(df['State'] == selected_state) & (df['Chaincode'] == selected_chaincode) & (df['Itemtype'] == selected_itemtype)].groupby('Containercode', observed=True)['SalesVolume'].sum().nlargest(3).reset_index()
303
+ bottom_containercodes = df[(df['State'] == selected_state) & (df['Chaincode'] == selected_chaincode) & (df['Itemtype'] == selected_itemtype)].groupby('Containercode', observed=True)['SalesVolume'].sum().nsmallest(3).reset_index()
304
+
305
+ # Get top and bottom 3 stores based on SalesVolume
306
+ top_stores = df[(df['State'] == selected_state) & (df['Chaincode'] == selected_chaincode) & (df['Itemtype'] == selected_itemtype)].groupby('Store', observed=True)['SalesVolume'].sum().nlargest(3).reset_index()
307
+ bottom_stores = df[(df['State'] == selected_state) & (df['Chaincode'] == selected_chaincode) & (df['Itemtype'] == selected_itemtype)].groupby('Store', observed=True)['SalesVolume'].sum().nsmallest(3).reset_index()
308
+
309
+ # Create a table with the top and bottom container codes and stores
310
+ st.write("### Top 3 Container Codes:")
311
+ st.dataframe(top_containercodes)
312
+
313
+ st.write("### Bottom 3 Container Codes:")
314
+ st.dataframe(bottom_containercodes)
315
+
316
+ st.write("### Top 3 Stores:")
317
+ st.dataframe(top_stores)
318
+
319
+ st.write("### Bottom 3 Stores:")
320
+ st.dataframe(bottom_stores)
321
  ##########################################################################################################
322
 
 
323
 
324
+ ########################################### CARD #2 ####################################################
325
  if st.session_state['active_card'] == 'card2':
326
+ # Identify the top 10 Itemtypes based on total SalesVolume
327
+ top_10_itemtypes = df.groupby('Itemtype')['SalesVolume'].sum().nlargest(10).index
328
+
329
+ # Filter the DataFrame to include only the top 10 Itemtypes
330
+ df = df[df['Itemtype'].isin(top_10_itemtypes)]
331
  # Dropdown to select item type (using session_state)
332
  st.session_state['selected_item_type'] = st.selectbox(
333
  'Select Item Type', df['Itemtype'].unique(),
 
434
  selected_item_type = st.selectbox("Select Item Type", item_type_options)
435
 
436
  # Dropdown for selecting the region (multiple selection allowed)
437
+ region_options = df['Region'].dropna().unique()
438
  selected_regions = st.multiselect("Select Region(s)", region_options, default=region_options)
439
 
440
  # Filter data based on selected item type and selected regions