import streamlit as st
import plotly.graph_objects as go
from pymongo import MongoClient
from datetime import datetime, timedelta
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import certifi
import json
import os
mongo_uri = "mongodb+srv://Agripredict:TjXSvMhOis49qH8E@cluster0.gek7n.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0"
if not mongo_uri:
st.error("MongoDB URI is not set!")
st.stop()
else:
# Connect to MongoDB with SSL certificate validation
client = MongoClient(mongo_uri, tlsCAFile=certifi.where())
db = client["AgriPredict"]
collection = db["WhiteSesame"]
# CSS to increase the width of the container
st.markdown("""
""", unsafe_allow_html=True)
st.title("🌾 AgriPredict Dashboard")
# Load the state-market dictionary from the JSON file
with open('all_state_market_dict.json', 'r') as file:
state_market_dict = json.load(file)
# UI for Dashboard
with st.container():
with st.expander("AgriPredict Dashboard", expanded=True):
# Adjust the columns to fit more elements within the container
col1, col2, col3, col4, col5, col6, col7 = st.columns([1.5, 1.5, 1.5, 1.5, 1.5, 3, 3])
# Buttons for periods
with col1:
if st.button('2W', key='2_weeks'):
st.session_state.selected_period = 14
with col2:
if st.button('1M', key='1_month'):
st.session_state.selected_period = 30
with col3:
if st.button('3M', key='3_months'):
st.session_state.selected_period = 90
with col4:
if st.button('1Y', key='1_year'):
st.session_state.selected_period = 365
with col5:
if st.button('5Y', key='5_year'):
st.session_state.selected_period = 1825
# Dropdown for states
with col6:
states = list(state_market_dict.keys())
selected_state = st.selectbox(
"Choose a state",
states,
key="state_selectbox",
index=0
)
# Dropdown for selecting between Price, Volume, or Both
with col7:
data_type = st.selectbox(
"Select Data Type",
["Price", "Volume", "Both"]
)
# Checkbox for market-wise analysis
st.write("")
with st.container():
market_wise = st.checkbox("Market wise", key="market_checkbox")
if market_wise:
# Get markets for the selected state
markets = state_market_dict.get(selected_state, [])
selected_market = st.selectbox(
"Choose a market",
markets,
key="market_selectbox",
index=0
)
query_filter = {"state": selected_state, "Market Name": selected_market}
else:
query_filter = {"state": selected_state}
# Add date filtering based on selected period
if 'selected_period' in st.session_state:
days_period = st.session_state.selected_period
query_filter["Reported Date"] = {
"$gte": datetime.now() - timedelta(days=days_period)
}
# Fetch data from MongoDB
try:
cursor = collection.find(query_filter)
data = list(cursor)
if data:
# Convert MongoDB data to a DataFrame
df = pd.DataFrame(data)
df['Reported Date'] = pd.to_datetime(df['Reported Date'])
# Group by Reported Date
df_grouped = (
df.groupby('Reported Date', as_index=False)
.agg({
'Arrivals (Tonnes)': 'sum',
'Modal Price (Rs./Quintal)': 'mean'
})
)
# Create a complete date range
date_range = pd.date_range(
start=df_grouped['Reported Date'].min(),
end=df_grouped['Reported Date'].max()
)
df_grouped = df_grouped.set_index('Reported Date').reindex(date_range).rename_axis('Reported Date').reset_index()
# Fill missing values
df_grouped['Arrivals (Tonnes)'] = df_grouped['Arrivals (Tonnes)'].fillna(
method='ffill').fillna(method='bfill')
df_grouped['Modal Price (Rs./Quintal)'] = df_grouped['Modal Price (Rs./Quintal)'].fillna(
method='ffill').fillna(method='bfill')
st.subheader(f"📈 Trend Graph for {selected_state} ({'Market: ' + selected_market if market_wise else 'State'})")
if data_type == "Both":
# Min-Max Scaling
scaler = MinMaxScaler()
df_grouped[['Scaled Price', 'Scaled Arrivals']] = scaler.fit_transform(
df_grouped[['Modal Price (Rs./Quintal)', 'Arrivals (Tonnes)']]
)
fig = go.Figure()
# Plot Scaled Price with actual values on hover
fig.add_trace(go.Scatter(
x=df_grouped['Reported Date'],
y=df_grouped['Scaled Price'],
mode='lines',
name='Scaled Price',
line=dict(width=1, color='green'),
text=df_grouped['Modal Price (Rs./Quintal)'], # Actual Modal Price values
hovertemplate='Date: %{x}
Scaled Price: %{y:.2f}
Actual Price: %{text:.2f}'
))
# Plot Scaled Arrivals with actual values on hover
fig.add_trace(go.Scatter(
x=df_grouped['Reported Date'],
y=df_grouped['Scaled Arrivals'],
mode='lines',
name='Scaled Arrivals',
line=dict(width=1, color='blue'),
text=df_grouped['Arrivals (Tonnes)'], # Actual Arrivals values
hovertemplate='Date: %{x}
Scaled Arrivals: %{y:.2f}
Actual Arrivals: %{text:.2f}'
))
fig.update_layout(
title="Price and Arrivals Trend",
xaxis_title='Date',
yaxis_title='Scaled Values',
template='plotly_white'
)
st.plotly_chart(fig)
elif data_type == "Price":
# Plot Modal Price
fig = go.Figure()
fig.add_trace(go.Scatter(
x=df_grouped['Reported Date'],
y=df_grouped['Modal Price (Rs./Quintal)'],
mode='lines',
name='Modal Price',
line=dict(width=1, color='green')
))
fig.update_layout(title="Modal Price Trend", xaxis_title='Date', yaxis_title='Price', template='plotly_white')
st.plotly_chart(fig)
elif data_type == "Volume":
# Plot Arrivals (Tonnes)
fig = go.Figure()
fig.add_trace(go.Scatter(
x=df_grouped['Reported Date'],
y=df_grouped['Arrivals (Tonnes)'],
mode='lines',
name='Arrivals',
line=dict(width=1, color='blue')
))
fig.update_layout(title="Arrivals Trend", xaxis_title='Date', yaxis_title='Volume', template='plotly_white')
st.plotly_chart(fig)
else:
st.warning("⚠️ No relevant data found for the selected options.")
else:
st.warning("⚠️ No data found for the selected filters.")
except Exception as e:
st.error(f"❌ Error fetching data: {e}")