Spaces:
Runtime error
Runtime error
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import matplotlib.pyplot as plt
|
3 |
+
import seaborn as sns
|
4 |
+
import gradio as gr
|
5 |
+
from darts import TimeSeries
|
6 |
+
from darts.models import TFTModel, NBEATSModel
|
7 |
+
from darts.dataprocessing.transformers import Scaler
|
8 |
+
from sklearn.preprocessing import LabelEncoder
|
9 |
+
import numpy as np
|
10 |
+
import io
|
11 |
+
|
12 |
+
# ----------------------------
|
13 |
+
# Load Dataset
|
14 |
+
# ----------------------------
|
15 |
+
df = pd.read_csv("dataset.csv") # <-- replace with your dataset file
|
16 |
+
df['datetime'] = pd.to_datetime(df['datetime'])
|
17 |
+
df = df.sort_values("datetime")
|
18 |
+
|
19 |
+
# Encode weather icons (categorical -> numeric)
|
20 |
+
encoder = LabelEncoder()
|
21 |
+
df['icon_encoded'] = encoder.fit_transform(df['icon'])
|
22 |
+
|
23 |
+
# ----------------------------
|
24 |
+
# Preprocessing for Forecasting
|
25 |
+
# ----------------------------
|
26 |
+
series = TimeSeries.from_dataframe(df, "datetime", "pv_output_kWh")
|
27 |
+
scaler = Scaler()
|
28 |
+
series_scaled = scaler.fit_transform(series)
|
29 |
+
|
30 |
+
# Pre-trained model (you can switch between TFT and N-BEATS)
|
31 |
+
model = TFTModel.load_from_checkpoint("tft_pretrained", work_dir="./") \
|
32 |
+
if TFTModel.exists("tft_pretrained", work_dir="./") else None
|
33 |
+
|
34 |
+
if model is None:
|
35 |
+
# fallback: train small model (for demo)
|
36 |
+
model = NBEATSModel(input_chunk_length=30, output_chunk_length=7, n_epochs=10)
|
37 |
+
model.fit(series_scaled)
|
38 |
+
|
39 |
+
# ----------------------------
|
40 |
+
# EDA FUNCTIONS
|
41 |
+
# ----------------------------
|
42 |
+
def eda_summary():
|
43 |
+
buf = io.StringIO()
|
44 |
+
df.describe().to_string(buf)
|
45 |
+
return buf.getvalue()
|
46 |
+
|
47 |
+
def eda_histogram(column):
|
48 |
+
plt.figure(figsize=(6,4))
|
49 |
+
sns.histplot(df[column], kde=True, bins=20)
|
50 |
+
plt.title(f"Distribution of {column}")
|
51 |
+
plt.tight_layout()
|
52 |
+
return plt.gcf()
|
53 |
+
|
54 |
+
def eda_correlation():
|
55 |
+
plt.figure(figsize=(8,6))
|
56 |
+
sns.heatmap(df.corr(), annot=True, cmap="coolwarm", fmt=".2f")
|
57 |
+
plt.title("Correlation Heatmap")
|
58 |
+
plt.tight_layout()
|
59 |
+
return plt.gcf()
|
60 |
+
|
61 |
+
def eda_timeseries():
|
62 |
+
plt.figure(figsize=(10,4))
|
63 |
+
plt.plot(df["datetime"], df["pv_output_kWh"], label="PV Output (kWh)")
|
64 |
+
plt.title("Time-Series Trend of PV Output")
|
65 |
+
plt.xlabel("Date")
|
66 |
+
plt.ylabel("PV Output (kWh)")
|
67 |
+
plt.legend()
|
68 |
+
plt.tight_layout()
|
69 |
+
return plt.gcf()
|
70 |
+
|
71 |
+
# ----------------------------
|
72 |
+
# FORECAST FUNCTION
|
73 |
+
# ----------------------------
|
74 |
+
def forecast_pv(horizon, weather_condition):
|
75 |
+
horizon_map = {"24 Hours": 24, "3 Days": 72, "7 Days": 168, "14 Days": 336}
|
76 |
+
steps = horizon_map[horizon]
|
77 |
+
|
78 |
+
forecast = model.predict(steps)
|
79 |
+
forecast = scaler.inverse_transform(forecast)
|
80 |
+
|
81 |
+
# Adjust for weather condition
|
82 |
+
adjustment = {
|
83 |
+
"Clear": 1.0,
|
84 |
+
"Partly Cloudy": 0.85,
|
85 |
+
"Cloudy": 0.65,
|
86 |
+
"Fog": 0.55,
|
87 |
+
"Smoke/Dust": 0.6,
|
88 |
+
"Winter": 0.7,
|
89 |
+
"Rain": 0.5
|
90 |
+
}
|
91 |
+
adj_factor = adjustment.get(weather_condition, 1.0)
|
92 |
+
forecast_adj = forecast * adj_factor
|
93 |
+
|
94 |
+
# Plot forecast
|
95 |
+
plt.figure(figsize=(10,4))
|
96 |
+
series[-7*24:].plot(label="History") # last 7 days history
|
97 |
+
forecast.plot(label="Forecast (Base)")
|
98 |
+
forecast_adj.plot(label=f"Forecast (Adjusted for {weather_condition})")
|
99 |
+
plt.legend()
|
100 |
+
plt.title(f"PV Forecast for {horizon}")
|
101 |
+
plt.tight_layout()
|
102 |
+
|
103 |
+
# Peak info
|
104 |
+
peak_time = forecast_adj.time_index[np.argmax(forecast_adj.values())]
|
105 |
+
peak_val = np.max(forecast_adj.values())
|
106 |
+
peak_info = f"🔺 Peak PV Output: {round(peak_val,2)} kWh at {peak_time}"
|
107 |
+
|
108 |
+
return plt.gcf(), peak_info
|
109 |
+
|
110 |
+
# ----------------------------
|
111 |
+
# GRADIO INTERFACE
|
112 |
+
# ----------------------------
|
113 |
+
eda_tab = gr.TabbedInterface(
|
114 |
+
[
|
115 |
+
gr.Interface(fn=eda_summary, inputs=[], outputs="text", title="Summary Stats"),
|
116 |
+
gr.Interface(fn=eda_histogram, inputs=gr.Dropdown(df.columns, label="Select Column"), outputs="plot", title="Histogram"),
|
117 |
+
gr.Interface(fn=eda_correlation, inputs=[], outputs="plot", title="Correlation Heatmap"),
|
118 |
+
gr.Interface(fn=eda_timeseries, inputs=[], outputs="plot", title="Time Series Trend")
|
119 |
+
],
|
120 |
+
tab_names=["Summary", "Histogram", "Correlation", "Time Series"]
|
121 |
+
)
|
122 |
+
|
123 |
+
forecast_tab = gr.Interface(
|
124 |
+
fn=forecast_pv,
|
125 |
+
inputs=[
|
126 |
+
gr.Radio(["24 Hours", "3 Days", "7 Days", "14 Days"], label="Select Forecast Horizon"),
|
127 |
+
gr.Dropdown(["Clear","Partly Cloudy","Cloudy","Fog","Smoke/Dust","Winter","Rain"], label="Weather Condition")
|
128 |
+
],
|
129 |
+
outputs=[
|
130 |
+
gr.Plot(label="Forecast Plot"),
|
131 |
+
gr.Textbox(label="Peak Info")
|
132 |
+
],
|
133 |
+
title="PV Forecasting"
|
134 |
+
)
|
135 |
+
|
136 |
+
app = gr.TabbedInterface([eda_tab, forecast_tab], tab_names=["EDA Dashboard", "Forecasting"])
|
137 |
+
|
138 |
+
if __name__ == "__main__":
|
139 |
+
app.launch()
|