Spaces:
Sleeping
Sleeping
ProtonDataLabs
commited on
Commit
•
ba7f8df
1
Parent(s):
2a243f7
Update app.py
Browse files
app.py
CHANGED
@@ -51,7 +51,7 @@ def load_data(active_card):
|
|
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 |
}
|
57 |
|
@@ -114,7 +114,7 @@ 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,
|
118 |
with col1:
|
119 |
if st.button("Sales Volume Trend"):
|
120 |
st.session_state['active_card'] = 'card1'
|
@@ -124,14 +124,14 @@ with col1:
|
|
124 |
st.session_state['selected_itemtype'] = None
|
125 |
st.session_state['selected_containercode'] = None
|
126 |
|
127 |
-
with col2:
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
|
136 |
with col3:
|
137 |
if st.button("Price Elasticity Coefficient Trend YoY"):
|
@@ -327,110 +327,110 @@ if st.session_state['active_card'] == 'card1':
|
|
327 |
|
328 |
|
329 |
########################################### CARD #2 ####################################################
|
330 |
-
if st.session_state['active_card'] == 'card2':
|
331 |
-
|
332 |
-
|
333 |
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
|
341 |
-
|
342 |
-
|
343 |
|
344 |
-
|
345 |
-
|
346 |
|
347 |
-
|
348 |
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
|
354 |
-
|
355 |
-
|
356 |
|
357 |
-
|
358 |
-
|
359 |
|
360 |
-
|
361 |
-
|
362 |
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
|
435 |
################################
|
436 |
if st.session_state['active_card'] == 'card3':
|
@@ -466,6 +466,11 @@ if st.session_state['active_card'] == 'card3':
|
|
466 |
|
467 |
# Drop rows where PE_Coeff is NaN (optional)
|
468 |
agg_df_filtered = agg_df_filtered.dropna(subset=['PE_Coeff'])
|
|
|
|
|
|
|
|
|
|
|
469 |
st.dataframe(agg_df_filtered)
|
470 |
st.write(agg_df_filtered.shape)
|
471 |
# Extract values for the current and previous years from row 1 and row 2 of the dataframe
|
@@ -485,25 +490,53 @@ if st.session_state['active_card'] == 'card3':
|
|
485 |
# Calculate PE Coefficient
|
486 |
pe_coeff = sales_volume_pct / unit_price_pct
|
487 |
|
488 |
-
|
489 |
st.latex(rf"""
|
490 |
-
\text{{Unit Price \% Change}} = \frac{{
|
491 |
""")
|
492 |
|
|
|
493 |
st.latex(rf"""
|
494 |
-
\text{{Sales Volume \% Change}} = \frac{{
|
495 |
""")
|
496 |
|
|
|
497 |
st.latex(rf"""
|
498 |
-
\text{{PE Coefficient}} = \frac{{
|
499 |
""")
|
500 |
-
|
|
|
501 |
st.markdown(f"""
|
502 |
-
###
|
503 |
-
|
504 |
-
|
505 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
506 |
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
507 |
# Plot the PE Coefficient with Plotly
|
508 |
fig = px.line(
|
509 |
agg_df_filtered,
|
|
|
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 |
}
|
57 |
|
|
|
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, col3 = st.columns(2)
|
118 |
with col1:
|
119 |
if st.button("Sales Volume Trend"):
|
120 |
st.session_state['active_card'] = 'card1'
|
|
|
124 |
st.session_state['selected_itemtype'] = None
|
125 |
st.session_state['selected_containercode'] = None
|
126 |
|
127 |
+
# with col2:
|
128 |
+
# if st.button("Sales Volume vs Median Unit Price Trend"):
|
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("Price Elasticity Coefficient Trend YoY"):
|
|
|
327 |
|
328 |
|
329 |
########################################### CARD #2 ####################################################
|
330 |
+
# if st.session_state['active_card'] == 'card2':
|
331 |
+
# # Identify the top 10 Itemtypes based on total SalesVolume
|
332 |
+
# top_10_itemtypes = df.groupby('Itemtype')['SalesVolume'].sum().nlargest(10).index
|
333 |
|
334 |
+
# # Filter the DataFrame to include only the top 10 Itemtypes
|
335 |
+
# df = df[df['Itemtype'].isin(top_10_itemtypes)]
|
336 |
+
# # Dropdown to select item type (using session_state)
|
337 |
+
# st.session_state['selected_item_type'] = st.selectbox(
|
338 |
+
# 'Select Item Type', df['Itemtype'].unique(),
|
339 |
+
# index=list(df['Itemtype'].unique()).index(st.session_state['selected_item_type']))
|
340 |
|
341 |
+
# # Dropdown to select the grouping category (container code, chain code, or state)
|
342 |
+
# group_by_option = st.selectbox('Group by', ['Containercode', 'Chaincode', 'State','Region'])
|
343 |
|
344 |
+
# # Multi-select checkbox to select multiple years
|
345 |
+
# selected_years = st.multiselect('Select Year(s)', [2021, 2022, 2023, 2024], default=[2021])
|
346 |
|
347 |
+
# st.subheader(f"Sales Volume & Unit Price Correlation for {group_by_option} in {', '.join(map(str, selected_years))}")
|
348 |
|
349 |
+
# # Convert 'Dt' column to datetime
|
350 |
+
# df['Dt'] = pd.to_datetime(df['Dt'], errors='coerce')
|
351 |
+
# df['Promo'] = np.where(df['Dt'].dt.month.astype(str).isin(['3', '4', '5', '6']), 'Promo', 'NoPromo')
|
352 |
+
# df["Promo"] = df["Promo"].astype("category")
|
353 |
|
354 |
+
# # Filter the dataframe based on the selected item type and selected years
|
355 |
+
# filtered_df = df[(df['Itemtype'] == st.session_state['selected_item_type']) & (df['Dt'].dt.year.isin(selected_years))]
|
356 |
|
357 |
+
# # Find the top 3 values based on total SalesVolume in the selected grouping category
|
358 |
+
# top_3_values = filtered_df.groupby(group_by_option, observed=True)['SalesVolume'].sum().nlargest(3).index
|
359 |
|
360 |
+
# # Filter the data for only the top 3 values
|
361 |
+
# top_group_data = filtered_df[filtered_df[group_by_option].isin(top_3_values)]
|
362 |
|
363 |
+
# # Aggregate data
|
364 |
+
# agg_df = top_group_data.groupby([group_by_option, 'Year', 'Week', 'Dt'], observed=True).agg({
|
365 |
+
# 'SalesVolume': 'sum',
|
366 |
+
# 'UnitPrice': 'mean'
|
367 |
+
# }).reset_index()
|
368 |
+
|
369 |
+
# # Create a new column 'week-year' for X-axis labels
|
370 |
+
# agg_df['week-year'] = agg_df['Dt'].dt.strftime('%U-%Y')
|
371 |
+
|
372 |
+
# # Loop through the top 3 values and create separate plots using Plotly
|
373 |
+
# for value in top_3_values:
|
374 |
+
# value_data = agg_df[agg_df[group_by_option] == value]
|
375 |
+
# # Assuming you have 'value_data' from your previous code
|
376 |
+
# mean_sales_volume = value_data['SalesVolume'].mean()
|
377 |
+
# mean_unit_price = value_data['UnitPrice'].mean()
|
378 |
+
|
379 |
+
# # Create a Plotly figure
|
380 |
+
# fig = go.Figure()
|
381 |
+
|
382 |
+
# # Add SalesVolume trace
|
383 |
+
# fig.add_trace(go.Scatter(
|
384 |
+
# x=value_data['week-year'],
|
385 |
+
# y=value_data['SalesVolume'],
|
386 |
+
# mode='lines+markers',
|
387 |
+
# name='SalesVolume',
|
388 |
+
# line=dict(color='blue'),
|
389 |
+
# hovertemplate='SalesVolume: %{y}<br>Week-Year: %{x}'
|
390 |
+
# ))
|
391 |
+
|
392 |
+
# # Add UnitPrice trace on a secondary Y-axis
|
393 |
+
# fig.add_trace(go.Scatter(
|
394 |
+
# x=value_data['week-year'],
|
395 |
+
# y=value_data['UnitPrice'],
|
396 |
+
# mode='lines+markers',
|
397 |
+
# name='UnitPrice',
|
398 |
+
# line=dict(color='green'),
|
399 |
+
# yaxis='y2',
|
400 |
+
# hovertemplate='UnitPrice: %{y}<br>Week-Year: %{x}'
|
401 |
+
# ))
|
402 |
+
# # Add mean line for SalesVolume
|
403 |
+
# fig.add_shape(type="line",
|
404 |
+
# x0=value_data['week-year'].min(), x1=value_data['week-year'].max(),
|
405 |
+
# y0=mean_sales_volume, y1=mean_sales_volume,
|
406 |
+
# line=dict(color="blue", width=2, dash="dash"),
|
407 |
+
# xref='x', yref='y')
|
408 |
+
|
409 |
+
# # Add mean line for UnitPrice (on secondary Y-axis)
|
410 |
+
# fig.add_shape(type="line",
|
411 |
+
# x0=value_data['week-year'].min(), x1=value_data['week-year'].max(),
|
412 |
+
# y0=mean_unit_price, y1=mean_unit_price,
|
413 |
+
# line=dict(color="green", width=2, dash="dash"),
|
414 |
+
# xref='x', yref='y2')
|
415 |
+
|
416 |
+
# # Update layout for dual axes
|
417 |
+
# fig.update_layout(
|
418 |
+
# template='plotly_white',
|
419 |
+
# title=f"SalesVolume and UnitPrice - {value} ({group_by_option})",
|
420 |
+
# xaxis_title='Week-Year',
|
421 |
+
# yaxis_title='Sales Volume',
|
422 |
+
# yaxis2=dict(title='UnitPrice', overlaying='y', side='right'),
|
423 |
+
# legend=dict(x=0.9, y=1.15),
|
424 |
+
# hovermode="x unified", # Show both values in a tooltip
|
425 |
+
# height=600,
|
426 |
+
# margin=dict(l=50, r=50, t=50, b=50)
|
427 |
+
# )
|
428 |
+
|
429 |
+
# # Rotate X-axis labels
|
430 |
+
# fig.update_xaxes(tickangle=90)
|
431 |
+
|
432 |
+
# # Display the Plotly figure in Streamlit
|
433 |
+
# st.plotly_chart(fig, use_container_width=True)
|
434 |
|
435 |
################################
|
436 |
if st.session_state['active_card'] == 'card3':
|
|
|
466 |
|
467 |
# Drop rows where PE_Coeff is NaN (optional)
|
468 |
agg_df_filtered = agg_df_filtered.dropna(subset=['PE_Coeff'])
|
469 |
+
agg_df_filtered = agg_df_filtered.rename(columns={
|
470 |
+
'SalesVolume_pct_change': 'SlVol%change',
|
471 |
+
'UnitPrice_pct_change': 'UnPr%change',
|
472 |
+
})
|
473 |
+
agg_df_filtered = agg_df_filtered.reset_index(drop=True)
|
474 |
st.dataframe(agg_df_filtered)
|
475 |
st.write(agg_df_filtered.shape)
|
476 |
# Extract values for the current and previous years from row 1 and row 2 of the dataframe
|
|
|
490 |
# Calculate PE Coefficient
|
491 |
pe_coeff = sales_volume_pct / unit_price_pct
|
492 |
|
493 |
+
st.markdown(f'''### Calculations for Price Elasticity Coefficient''')
|
494 |
st.latex(rf"""
|
495 |
+
\text{{Unit Price \% Change}} = \frac{{{unit_price_current_year:.2f} - {unit_price_previous_year:.2f}}}{{{unit_price_previous_year:.2f}}} \times 100 = {unit_price_pct:.2f}\%
|
496 |
""")
|
497 |
|
498 |
+
# Sales Volume % Change
|
499 |
st.latex(rf"""
|
500 |
+
\text{{Sales Volume \% Change}} = \frac{{{sales_volume_current_year:.2f} - {sales_volume_previous_year:.2f}}}{{{sales_volume_previous_year:.2f}}} \times 100 = {sales_volume_pct:.2f}\%
|
501 |
""")
|
502 |
|
503 |
+
# PE Coefficient
|
504 |
st.latex(rf"""
|
505 |
+
\text{{PE Coefficient}} = \frac{{{sales_volume_pct:.2f}}}{{{unit_price_pct:.2f}}} = {pe_coeff:.2f}
|
506 |
""")
|
507 |
+
|
508 |
+
# Explanation for PE Coefficient Conditions
|
509 |
st.markdown(f"""
|
510 |
+
### Interpretation of Price Elasticity (PE) Coefficient:
|
511 |
+
The Price Elasticity (PE) coefficient reflects how sensitive sales volume is to changes in unit price.
|
512 |
+
|
513 |
+
- If the **PE coefficient is positive**:
|
514 |
+
1. When the price increases, sales volume increases.
|
515 |
+
2. When the price decreases, sales volume decreases.
|
516 |
+
|
517 |
+
- If the **PE coefficient is negative**:
|
518 |
+
1. When the price increases, sales volume decreases.
|
519 |
+
2. When the price decreases, sales volume increases.
|
520 |
+
|
521 |
""")
|
522 |
+
|
523 |
+
# Dynamic analysis based on the calculated PE coefficient and signs of changes
|
524 |
+
if unit_price_pct > 0 and sales_volume_pct > 0:
|
525 |
+
st.warning(f"""
|
526 |
+
Both unit price and sales volume increased (refer first and second row of the table). The PE coefficient of **{pe_coeff:.2f}** indicates that for every 1% increase in unit price, sales volume increased by approximately **{pe_coeff:.2f}%**.
|
527 |
+
""")
|
528 |
+
elif unit_price_pct < 0 and sales_volume_pct < 0:
|
529 |
+
st.warning(f"""
|
530 |
+
Both unit price and sales volume decreased (refer first and second row of the table). The PE coefficient of **{pe_coeff:.2f}** suggests that for every 1% decrease in unit price, sales volume decreased by approximately **{pe_coeff:.2f}%**.
|
531 |
+
""")
|
532 |
+
elif unit_price_pct > 0 and sales_volume_pct < 0:
|
533 |
+
st.warning(f"""
|
534 |
+
The unit price increased while sales volume decreased (refer first and second row of the table). The negative PE coefficient of **{pe_coeff:.2f}** means that for every 1% increase in unit price, sales volume fell by approximately **{abs(pe_coeff):.2f}%**.
|
535 |
+
""")
|
536 |
+
elif unit_price_pct < 0 and sales_volume_pct > 0:
|
537 |
+
st.warning(f"""
|
538 |
+
The unit price decreased while sales volume increased (refer first and second row of the table). The negative PE coefficient of **{pe_coeff:.2f}** implies that for every 1% decrease in unit price, sales volume increased by approximately **{abs(pe_coeff):.2f}%**.
|
539 |
+
""")
|
540 |
# Plot the PE Coefficient with Plotly
|
541 |
fig = px.line(
|
542 |
agg_df_filtered,
|