Spaces:
Build error
Build error
| 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") | |