Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -13,7 +13,7 @@ st.set_page_config(
|
|
| 13 |
)
|
| 14 |
|
| 15 |
# --- Title & Description ---
|
| 16 |
-
st.title("📈Climate Forecasting")
|
| 17 |
st.markdown(
|
| 18 |
"""
|
| 19 |
Upload your historical weather CSV (with columns: `date`, `meantemp`, `humidity`,
|
|
@@ -23,20 +23,28 @@ st.markdown(
|
|
| 23 |
|
| 24 |
# --- Sidebar Controls ---
|
| 25 |
st.sidebar.header("Application Features")
|
| 26 |
-
|
| 27 |
"Temperature Forecast": "meantemp",
|
| 28 |
"Humidity Forecast": "humidity",
|
| 29 |
"Wind Speed Forecast": "wind_speed",
|
| 30 |
"Mean Pressure Forecast": "meanpressure"
|
| 31 |
}
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
periods = st.sidebar.slider(
|
| 37 |
"Days to Forecast", min_value=30, max_value=365, value=180, step=30
|
| 38 |
)
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
# --- File Uploader ---
|
| 41 |
uploaded_file = st.file_uploader("Upload CSV", type=["csv"])
|
| 42 |
if not uploaded_file:
|
|
@@ -45,37 +53,40 @@ if not uploaded_file:
|
|
| 45 |
|
| 46 |
# --- Load & Preprocess ---
|
| 47 |
df = pd.read_csv(uploaded_file)
|
| 48 |
-
df.rename(columns={"date": "ds"
|
| 49 |
df["ds"] = pd.to_datetime(df["ds"])
|
| 50 |
st.subheader("Data Preview")
|
| 51 |
st.dataframe(df.head())
|
| 52 |
|
| 53 |
# --- Forecasting Function ---
|
| 54 |
def make_and_plot(df: pd.DataFrame, col: str, label: str):
|
| 55 |
-
# prepare
|
| 56 |
tmp = df[["ds", col]].dropna().rename(columns={col: "y"})
|
| 57 |
if tmp.empty:
|
| 58 |
st.warning(f"No data for {label}. Skipping.")
|
| 59 |
return
|
| 60 |
|
| 61 |
-
#
|
| 62 |
m = Prophet()
|
| 63 |
m.fit(tmp)
|
| 64 |
|
| 65 |
-
#
|
| 66 |
future = m.make_future_dataframe(periods=periods)
|
| 67 |
fcst = m.predict(future)
|
| 68 |
|
| 69 |
-
#
|
|
|
|
| 70 |
st.subheader(f"{label}")
|
| 71 |
fig = px.line(
|
| 72 |
-
fcst,
|
|
|
|
|
|
|
| 73 |
title=f"{label} Forecast",
|
| 74 |
-
labels={"ds": "Date", "yhat": f"Forecasted {label}"}
|
|
|
|
| 75 |
)
|
| 76 |
st.plotly_chart(fig, use_container_width=True)
|
| 77 |
|
| 78 |
-
#
|
| 79 |
st.write("Latest Forecast Values")
|
| 80 |
st.dataframe(
|
| 81 |
fcst[["ds", "yhat", "yhat_lower", "yhat_upper"]].tail(),
|
|
@@ -87,13 +98,13 @@ def make_and_plot(df: pd.DataFrame, col: str, label: str):
|
|
| 87 |
}
|
| 88 |
)
|
| 89 |
|
| 90 |
-
#
|
| 91 |
st.write("Trend & Seasonality")
|
| 92 |
comp_fig = m.plot_components(fcst)
|
| 93 |
st.pyplot(comp_fig)
|
| 94 |
|
| 95 |
-
# ---
|
| 96 |
-
for label, col in
|
| 97 |
if selected[label]:
|
| 98 |
make_and_plot(df, col, label)
|
| 99 |
|
|
|
|
| 13 |
)
|
| 14 |
|
| 15 |
# --- Title & Description ---
|
| 16 |
+
st.title("📈 ForecastMaster: Delhi Climate Forecasting")
|
| 17 |
st.markdown(
|
| 18 |
"""
|
| 19 |
Upload your historical weather CSV (with columns: `date`, `meantemp`, `humidity`,
|
|
|
|
| 23 |
|
| 24 |
# --- Sidebar Controls ---
|
| 25 |
st.sidebar.header("Application Features")
|
| 26 |
+
FEATURES = {
|
| 27 |
"Temperature Forecast": "meantemp",
|
| 28 |
"Humidity Forecast": "humidity",
|
| 29 |
"Wind Speed Forecast": "wind_speed",
|
| 30 |
"Mean Pressure Forecast": "meanpressure"
|
| 31 |
}
|
| 32 |
+
# Checkbox for each feature
|
| 33 |
+
selected = {label: st.sidebar.checkbox(label, value=True) for label in FEATURES}
|
| 34 |
+
|
| 35 |
+
# Forecast horizon
|
| 36 |
periods = st.sidebar.slider(
|
| 37 |
"Days to Forecast", min_value=30, max_value=365, value=180, step=30
|
| 38 |
)
|
| 39 |
|
| 40 |
+
# --- Color Palette ---
|
| 41 |
+
FEATURE_COLORS = {
|
| 42 |
+
"Temperature Forecast": "#EF553B", # red
|
| 43 |
+
"Humidity Forecast": "#00CC96", # green
|
| 44 |
+
"Wind Speed Forecast": "#636EFA", # blue
|
| 45 |
+
"Mean Pressure Forecast": "#AB63FA", # purple
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
# --- File Uploader ---
|
| 49 |
uploaded_file = st.file_uploader("Upload CSV", type=["csv"])
|
| 50 |
if not uploaded_file:
|
|
|
|
| 53 |
|
| 54 |
# --- Load & Preprocess ---
|
| 55 |
df = pd.read_csv(uploaded_file)
|
| 56 |
+
df.rename(columns={"date": "ds"}, inplace=True)
|
| 57 |
df["ds"] = pd.to_datetime(df["ds"])
|
| 58 |
st.subheader("Data Preview")
|
| 59 |
st.dataframe(df.head())
|
| 60 |
|
| 61 |
# --- Forecasting Function ---
|
| 62 |
def make_and_plot(df: pd.DataFrame, col: str, label: str):
|
|
|
|
| 63 |
tmp = df[["ds", col]].dropna().rename(columns={col: "y"})
|
| 64 |
if tmp.empty:
|
| 65 |
st.warning(f"No data for {label}. Skipping.")
|
| 66 |
return
|
| 67 |
|
| 68 |
+
# Fit Prophet model
|
| 69 |
m = Prophet()
|
| 70 |
m.fit(tmp)
|
| 71 |
|
| 72 |
+
# Create future and forecast
|
| 73 |
future = m.make_future_dataframe(periods=periods)
|
| 74 |
fcst = m.predict(future)
|
| 75 |
|
| 76 |
+
# Plot with custom color
|
| 77 |
+
color = FEATURE_COLORS.get(label, "#333333")
|
| 78 |
st.subheader(f"{label}")
|
| 79 |
fig = px.line(
|
| 80 |
+
fcst,
|
| 81 |
+
x="ds",
|
| 82 |
+
y="yhat",
|
| 83 |
title=f"{label} Forecast",
|
| 84 |
+
labels={"ds": "Date", "yhat": f"Forecasted {label}"},
|
| 85 |
+
color_discrete_sequence=[color]
|
| 86 |
)
|
| 87 |
st.plotly_chart(fig, use_container_width=True)
|
| 88 |
|
| 89 |
+
# Show latest forecast table
|
| 90 |
st.write("Latest Forecast Values")
|
| 91 |
st.dataframe(
|
| 92 |
fcst[["ds", "yhat", "yhat_lower", "yhat_upper"]].tail(),
|
|
|
|
| 98 |
}
|
| 99 |
)
|
| 100 |
|
| 101 |
+
# Trend & seasonality
|
| 102 |
st.write("Trend & Seasonality")
|
| 103 |
comp_fig = m.plot_components(fcst)
|
| 104 |
st.pyplot(comp_fig)
|
| 105 |
|
| 106 |
+
# --- Generate Forecasts ---
|
| 107 |
+
for label, col in FEATURES.items():
|
| 108 |
if selected[label]:
|
| 109 |
make_and_plot(df, col, label)
|
| 110 |
|