import streamlit as st import pandas as pd import plotly.graph_objects as go import matplotlib.pyplot as plt from prophet import Prophet # --- Page Configuration --- st.set_page_config( page_title="Forecast", page_icon="📈", layout="centered", initial_sidebar_state="expanded" ) # --- Title and Description --- st.title("📈Climate Forecasting") st.markdown( """ Upload your historical weather CSV (columns: `date`, `meantemp`, `humidity`, `wind_speed`, `meanpressure`) and choose which forecasts to view. """ ) # --- Sidebar Feature Selection --- st.sidebar.header("Application Features") FEATURES = { "Temperature Forecast": "meantemp", "Humidity Forecast": "humidity", "Wind Speed Forecast": "wind_speed", "Mean Pressure Forecast": "meanpressure" } selected = {label: st.sidebar.checkbox(label, value=True) for label in FEATURES} periods = st.sidebar.slider("Days to Forecast", 30, 365, 180, step=30) # --- Color Palette --- FEATURE_COLORS = { "Temperature Forecast": "#EF553B", # red "Humidity Forecast": "#00CC96", # green "Wind Speed Forecast": "#636EFA", # blue "Mean Pressure Forecast": "#AB63FA", # purple } # --- File Upload --- uploaded_file = st.file_uploader("Upload CSV", type=["csv"]) if not uploaded_file: st.info("Awaiting CSV upload...") st.stop() # --- Load & Preprocess Data --- df = pd.read_csv(uploaded_file) df.rename(columns={"date": "ds"}, inplace=True) df["ds"] = pd.to_datetime(df["ds"]) st.subheader("Data Preview") st.dataframe(df.head()) # --- Forecast Function --- def make_and_plot(df: pd.DataFrame, col: str, label: str): data = df[["ds", col]].dropna().rename(columns={col: "y"}) if data.empty: st.warning(f"No data found for {label}. Skipping.") return model = Prophet() model.fit(data) future = model.make_future_dataframe(periods=periods) forecast = model.predict(future) # Split historical vs future last_actual_date = data["ds"].max() historical = forecast[forecast["ds"] <= last_actual_date] predicted = forecast[forecast["ds"] > last_actual_date] color_hist = "#1f77b4" color_fore = FEATURE_COLORS.get(label, "#FF7F0E") # --- Plot --- st.subheader(f"{label}") fig = go.Figure() fig.add_trace(go.Scatter( x=historical["ds"], y=historical["yhat"], mode="lines", name="Historical", line=dict(color=color_hist) )) fig.add_trace(go.Scatter( x=predicted["ds"], y=predicted["yhat"], mode="lines", name="Forecast", line=dict(color=color_fore, dash="dash") )) fig.update_layout( title=f"{label} (Historical vs Forecasted)", xaxis_title="Date", yaxis_title=label, legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1) ) st.plotly_chart(fig, use_container_width=True) # --- Forecast Table --- st.write("Latest Forecast Values") st.dataframe(predicted[["ds", "yhat", "yhat_lower", "yhat_upper"]].tail(), column_config={ "ds": "Date", "yhat": "Forecasted", "yhat_lower": "Lower Bound", "yhat_upper": "Upper Bound" }) # --- Trend and Seasonality --- st.write("Trend and Seasonality Components") components = model.plot_components(forecast) st.pyplot(components) # --- Run Forecasts Based on User Selection --- for label, col in FEATURES.items(): if selected[label]: make_and_plot(df, col, label) # --- Footer --- st.markdown("---") st.caption("Built with ❤️ using Streamlit & Prophet • © 2025")