Spaces:
Running
Running
| import streamlit as st | |
| import pandas as pd | |
| import plotly.graph_objects as go | |
| import io | |
| import calendar | |
| import numpy as np | |
| def plot_data(original_df, future_df, last_date, model, days): | |
| actual_last_df = original_df[original_df['Reported Date'] > (last_date - pd.Timedelta(days=days))] | |
| predicted_plot_df = actual_last_df[['Reported Date']].copy() | |
| predicted_plot_df['Modal Price (Rs./Quintal)'] = model.predict( | |
| actual_last_df.drop(columns=['Modal Price (Rs./Quintal)', 'Reported Date'], errors='ignore')) | |
| predicted_plot_df['Type'] = 'Actual' | |
| future_plot_df = future_df[['Reported Date', 'Modal Price (Rs./Quintal)']].copy() | |
| future_plot_df['Type'] = 'Forecasted' | |
| last_actual_point = predicted_plot_df.iloc[[-1]].copy() | |
| last_actual_point['Type'] = 'Forecasted' | |
| future_plot_df = pd.concat([last_actual_point, future_plot_df]) | |
| plot_df = pd.concat([predicted_plot_df, future_plot_df]) | |
| fig = go.Figure() | |
| for plot_type, color, dash in [('Actual', 'blue', 'solid'), ('Forecasted', 'red', 'dash')]: | |
| data = plot_df[plot_df['Type'] == plot_type] | |
| fig.add_trace(go.Scatter(x=data['Reported Date'], y=data['Modal Price (Rs./Quintal)'], mode='lines', name=f"{plot_type} Data", line=dict(color=color, dash=dash))) | |
| fig.update_layout(title="Actual vs Forecasted Modal Price (Rs./Quintal)", xaxis_title="Date", yaxis_title="Modal Price (Rs./Quintal)", template="plotly_white") | |
| st.plotly_chart(fig, use_container_width=True) | |
| def download_button(future_df: pd.DataFrame, key: str): | |
| download_df = future_df[['Reported Date', 'Modal Price (Rs./Quintal)']].copy() | |
| download_df['Reported Date'] = pd.to_datetime(download_df['Reported Date']).dt.strftime('%Y-%m-%d') | |
| towrite = io.BytesIO() | |
| with pd.ExcelWriter(towrite, engine='xlsxwriter') as writer: | |
| download_df.to_excel(writer, index=False, sheet_name='Forecast') | |
| towrite.seek(0) | |
| st.download_button(label="Download Forecast as Excel", data=towrite, file_name=f"forecast_{key}.xlsx") | |
| def display_statistics(df): | |
| st.title("π National Market Statistics Dashboard") | |
| st.markdown(""" | |
| <style> | |
| h1 { | |
| color: #2e7d32; | |
| font-size: 36px; | |
| font-weight: bold; | |
| } | |
| h3 { | |
| color: #388e3c; | |
| font-size: 28px; | |
| font-weight: 600; | |
| } | |
| p { | |
| font-size: 16px; | |
| line-height: 1.6; | |
| } | |
| .highlight { | |
| background-color: #f1f8e9; | |
| padding: 10px; | |
| border-radius: 8px; | |
| font-size: 16px; | |
| color: #2e7d32; | |
| font-weight: 500; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Ensure 'Reported Date' is in datetime format | |
| df['Reported Date'] = pd.to_datetime(df['Reported Date']) | |
| national_data = df.groupby('Reported Date').agg({ | |
| 'Modal Price (Rs./Quintal)': 'mean', | |
| 'Arrivals (Tonnes)': 'sum' | |
| }).reset_index() | |
| st.subheader("ποΈ Key Statistics") | |
| latest_date = national_data['Reported Date'].max() | |
| latest_price = national_data[national_data['Reported Date'] == latest_date]['Modal Price (Rs./Quintal)'].mean() | |
| latest_arrivals = national_data[national_data['Reported Date'] == latest_date]['Arrivals (Tonnes)'].sum() | |
| st.markdown("<p class='highlight'>This section provides the most recent statistics for the market. It includes the latest available date, the average price of commodities, and the total quantity of goods arriving at the market. These metrics offer an up-to-date snapshot of market conditions.</p>", unsafe_allow_html=True) | |
| st.write(f"**Latest Date**: {latest_date.strftime('%Y-%m-%d')}") | |
| st.write(f"**Latest Modal Price**: {latest_price:.2f} Rs./Quintal") | |
| st.write(f"**Latest Arrivals**: {latest_arrivals:.2f} Tonnes") | |
| st.subheader("π This Day in Previous Years") | |
| st.markdown("<p class='highlight'>This table shows the modal price and total arrivals for this exact day across previous years. It provides a historical perspective to compare against current market conditions. This section examines historical data for the same day in previous years. By analyzing trends for this specific day, you can identify seasonal patterns, supply-demand changes, or any deviations that might warrant closer attention.</p>", unsafe_allow_html=True) | |
| today = latest_date | |
| previous_years_data = national_data[national_data['Reported Date'].dt.dayofyear == today.dayofyear].copy() | |
| if not previous_years_data.empty: | |
| previous_years_data['Year'] = previous_years_data['Reported Date'].dt.year.astype(str) | |
| display_data = (previous_years_data[['Year', 'Modal Price (Rs./Quintal)', 'Arrivals (Tonnes)']] | |
| .sort_values(by='Year', ascending=False) | |
| .reset_index(drop=True)) | |
| st.table(display_data) | |
| else: | |
| st.write("No historical data available for this day in previous years.") | |
| st.subheader("π Monthly Averages Over Years") | |
| st.markdown("<p class='highlight'>This section displays the average modal prices and arrivals for each month across all years. It helps identify seasonal trends and peak activity months, which can be crucial for inventory planning and market predictions.</p>", unsafe_allow_html=True) | |
| national_data['Month'] = national_data['Reported Date'].dt.month | |
| monthly_avg_price = national_data.groupby('Month')['Modal Price (Rs./Quintal)'].mean().reset_index() | |
| monthly_avg_arrivals = national_data.groupby('Month')['Arrivals (Tonnes)'].mean().reset_index() | |
| monthly_avg = pd.merge(monthly_avg_price, monthly_avg_arrivals, on='Month') | |
| monthly_avg['Month'] = monthly_avg['Month'].apply(lambda x: calendar.month_name[x]) | |
| monthly_avg.columns = ['Month', 'Average Modal Price (Rs./Quintal)', 'Average Arrivals (Tonnes)'] | |
| st.write(monthly_avg) | |
| st.subheader("π Yearly Averages") | |
| st.markdown("<p class='highlight'>Yearly averages provide insights into long-term trends in pricing and arrivals. By examining these values, you can detect overall growth, stability, or volatility in the market.</p>", unsafe_allow_html=True) | |
| national_data['Year'] = national_data['Reported Date'].dt.year | |
| yearly_avg_price = national_data.groupby('Year')['Modal Price (Rs./Quintal)'].mean().reset_index() | |
| yearly_sum_arrivals = national_data.groupby('Year')['Arrivals (Tonnes)'].sum().reset_index() | |
| yearly_avg = pd.merge(yearly_avg_price, yearly_sum_arrivals, on='Year') | |
| yearly_avg['Year'] = yearly_avg['Year'].apply(lambda x: f"{int(x)}") | |
| yearly_avg.columns = ['Year', 'Average Modal Price (Rs./Quintal)', 'Average Arrivals (Tonnes)'] | |
| st.write(yearly_avg) | |
| st.subheader("π Largest Daily Price Changes (Past Year)") | |
| st.markdown("<p class='highlight'>This analysis identifies the most significant daily price changes in the past year. These fluctuations can highlight periods of market volatility, potentially caused by external factors like weather, policy changes, or supply chain disruptions.</p>", unsafe_allow_html=True) | |
| one_year_ago = latest_date - pd.DateOffset(years=1) | |
| recent_data = national_data[national_data['Reported Date'] >= one_year_ago].copy() | |
| recent_data['Daily Change (%)'] = recent_data['Modal Price (Rs./Quintal)'].pct_change() * 100 | |
| largest_changes = recent_data[['Reported Date', 'Modal Price (Rs./Quintal)', 'Daily Change (%)']].nlargest(5, 'Daily Change (%)') | |
| largest_changes['Reported Date'] = largest_changes['Reported Date'].dt.date | |
| largest_changes = largest_changes.reset_index(drop=True) | |
| st.write(largest_changes) | |
| st.subheader("π Top 5 Highest and Lowest Prices (Past Year)") | |
| st.markdown("<p class='highlight'>This section highlights the highest and lowest prices over the past year. These values reflect the extremes of market dynamics, helping to understand price ceilings and floors in the recent period.</p>", unsafe_allow_html=True) | |
| highest_prices = recent_data.nlargest(5, 'Modal Price (Rs./Quintal)')[['Reported Date', 'Modal Price (Rs./Quintal)']] | |
| lowest_prices = recent_data.nsmallest(5, 'Modal Price (Rs./Quintal)')[['Reported Date', 'Modal Price (Rs./Quintal)']] | |
| highest_prices['Reported Date'] = highest_prices['Reported Date'].dt.date | |
| lowest_prices['Reported Date'] = lowest_prices['Reported Date'].dt.date | |
| highest_prices = highest_prices.reset_index(drop=True) | |
| lowest_prices = lowest_prices.reset_index(drop=True) | |
| st.write("**Top 5 Highest Prices**") | |
| st.write(highest_prices) | |
| st.write("**Top 5 Lowest Prices**") | |
| st.write(lowest_prices) | |
| st.subheader("ποΈ Data Snapshot") | |
| st.markdown("<p class='highlight'>This snapshot provides a concise overview of the latest data, including rolling averages and lagged values. These metrics help identify short-term trends and lagged effects in pricing.</p>", unsafe_allow_html=True) | |
| national_data['Rolling Mean (14 Days)'] = national_data['Modal Price (Rs./Quintal)'].rolling(window=14).mean() | |
| national_data['Lag (14 Days)'] = national_data['Modal Price (Rs./Quintal)'].shift(14) | |
| national_data['Reported Date'] = national_data['Reported Date'].dt.date | |
| national_data = national_data.sort_values(by='Reported Date', ascending=False) | |
| st.dataframe(national_data.head(14).reset_index(drop=True), use_container_width=True, height=525) | |
| editable_spreadsheet() | |
| def editable_spreadsheet(): | |
| st.title("Sowing Report Prediction Model") | |
| # Excel file uploader | |
| uploaded_file = st.file_uploader("Upload your Excel file", type=['xlsx']) | |
| # Check if an Excel file is uploaded | |
| if uploaded_file is not None: | |
| # Read the Excel file | |
| df_excel = pd.read_excel(uploaded_file) | |
| # Display the DataFrame from the Excel file | |
| st.write("Excel data loaded:", df_excel) | |
| # Form for inputting filtering options and area for calculation | |
| with st.form("input_form"): | |
| input_region = st.text_input("Enter Region to Filter By", placeholder="Region Name") | |
| input_season = st.text_input("Enter Season to Filter By", placeholder="Season (e.g., Winter)") | |
| input_area = st.number_input("Enter Area (in hectares) for Production Calculation", min_value=0.0, format="%.2f") | |
| submit_button = st.form_submit_button("Calculate Production") | |
| if submit_button: | |
| if input_region and input_season and input_area > 0: | |
| # Filter data by the region and season specified | |
| filtered_df = df_excel[ | |
| (df_excel['Region'].str.lower() == input_region.lower()) & | |
| (df_excel['Season'].str.lower() == input_season.lower()) | |
| ] | |
| if not filtered_df.empty: | |
| process_dataframe(filtered_df, input_area) | |
| else: | |
| st.error("No data found for the specified region and season.") | |
| else: | |
| st.error("Please enter valid region, season, and area to proceed.") | |
| def process_dataframe(df, area): | |
| if 'Yield' in df.columns: | |
| average_yield = df['Yield'].mean() | |
| predicted_production = average_yield * area | |
| st.success(f"The predicted Production Volume for the specified region and season is: {predicted_production:.2f} units") | |
| else: | |
| st.error("The DataFrame does not contain a necessary 'Yield' column for calculation.") | |