|
|
|
|
|
import pandas as pd |
|
import matplotlib.pyplot as plt |
|
from prophet import Prophet |
|
import gradio as gr |
|
import pytz |
|
|
|
|
|
df = pd.read_csv("https://data.open-power-system-data.org/time_series/2020-10-06/time_series_60min_singleindex.csv", parse_dates=["utc_timestamp"]) |
|
|
|
|
|
df['utc_timestamp'] = pd.to_datetime(df['utc_timestamp']).dt.tz_convert('Europe/Berlin') |
|
|
|
|
|
df_prophet = df[["utc_timestamp", "DE_load_actual_entsoe_transparency"]].copy() |
|
df_prophet = df_prophet.rename(columns={"utc_timestamp": "ds", "DE_load_actual_entsoe_transparency": "y"}) |
|
df_prophet["ds"] = df_prophet["ds"].dt.tz_localize(None) |
|
df_prophet = df_prophet.dropna() |
|
|
|
|
|
df_prophet = df_prophet[df_prophet['ds'].dt.year == 2020] |
|
|
|
|
|
model = Prophet() |
|
model.fit(df_prophet) |
|
|
|
|
|
def forecast_plot(hours): |
|
future = model.make_future_dataframe(periods=hours, freq='H') |
|
forecast = model.predict(future) |
|
forecast['ds_local'] = pd.to_datetime(forecast['ds']).dt.tz_localize('UTC').dt.tz_convert('Europe/Berlin') |
|
|
|
|
|
peak_demand = forecast['yhat'].max() |
|
peak_time = forecast['ds_local'][forecast['yhat'].idxmax()] |
|
lower_bound = forecast['yhat_lower'].min() |
|
upper_bound = forecast['yhat_upper'].max() |
|
|
|
|
|
plt.figure(figsize=(12,6)) |
|
plt.plot(forecast['ds_local'], forecast['yhat'], label='Forecast', color='#FF6347', linewidth=2) |
|
plt.fill_between(forecast['ds_local'], forecast['yhat_lower'], forecast['yhat_upper'], alpha=0.3, color='#FF6347') |
|
plt.xlabel("Local Time (Europe/Berlin)", fontsize=12, fontweight='bold') |
|
plt.ylabel("Energy Load (MW)", fontsize=12, fontweight='bold') |
|
plt.title("β‘ German Energy Load Forecast (Zoomed into Future)", fontsize=16, fontweight='bold') |
|
plt.legend() |
|
plt.grid(True, linestyle='--', alpha=0.6) |
|
plt.xticks(rotation=45) |
|
plt.tight_layout() |
|
plt.show() |
|
|
|
|
|
explanation = f""" |
|
## π **Forecast Highlights** |
|
- **Peak Energy Demand**: {peak_demand:.2f} MW at **{peak_time.strftime('%Y-%m-%d %H:%M:%S')}**. |
|
- **Confidence Interval**: The forecasted energy load is expected to be between |
|
**{lower_bound:.2f} MW** and **{upper_bound:.2f} MW**. |
|
- The trend shows that the energy demand is expected to [increase/decrease], |
|
with a potential peak at the specified time. |
|
\n\n |
|
## π **Key Observations**: |
|
- The forecast suggests that **energy demand** will **reach its highest point** at **{peak_time.strftime('%H:%M')}**. |
|
- This peak could be a critical time for grid management to prevent overloading. |
|
- **Confidence interval** gives us a range, helping to understand the possible **fluctuations in demand**. |
|
""" |
|
|
|
|
|
return plt, explanation |
|
|
|
|
|
gr.Interface( |
|
fn=forecast_plot, |
|
inputs=gr.Slider(24, 168, step=24, label="Forecast Hours (1 to 7 days)"), |
|
outputs=[gr.Plot(), gr.Textbox()], |
|
title="β‘ Smart Energy Load Forecasting (Germany)", |
|
description="Predict the energy demand using Facebook Prophet. Select the number of hours to forecast (1-7 days).", |
|
theme="huggingface", |
|
).launch() |
|
|