File size: 3,712 Bytes
c2f6cad
 
457438b
c2f6cad
 
 
457438b
c2f6cad
441607f
c2f6cad
 
 
 
 
457438b
441607f
c2f6cad
 
457438b
 
c2f6cad
 
 
457438b
c2f6cad
f47e834
c2f6cad
 
 
 
 
f47e834
457438b
c2f6cad
f47e834
 
 
 
 
 
 
 
457438b
c2f6cad
 
 
 
 
457438b
c2f6cad
f47e834
c2f6cad
 
 
 
457438b
c2f6cad
457438b
 
 
c2f6cad
 
457438b
 
 
 
 
c2f6cad
457438b
 
 
 
c2f6cad
457438b
 
 
 
c2f6cad
457438b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2f6cad
 
 
457438b
c2f6cad
457438b
 
 
 
 
 
 
c2f6cad
457438b
 
 
 
c2f6cad
457438b
f47e834
c2f6cad
 
 
 
 
457438b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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")