isana25's picture
Update app.py
1687946 verified
# app.py
import pandas as pd
import matplotlib.pyplot as plt
from prophet import Prophet
import gradio as gr
import pytz
# Step 1: Download the dataset from Open Power System Data
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"])
# Step 2: Convert UTC to Europe/Berlin timezone
df['utc_timestamp'] = pd.to_datetime(df['utc_timestamp']).dt.tz_convert('Europe/Berlin')
# Step 3: Prepare the data for Prophet
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) # Remove timezone
df_prophet = df_prophet.dropna() # Drop missing values
# Optional: Filter data for one year (2020)
df_prophet = df_prophet[df_prophet['ds'].dt.year == 2020]
# Step 4: Train the Prophet model
model = Prophet()
model.fit(df_prophet)
# Step 5: Create future DataFrame and forecast
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')
# Calculate the highlights from the forecast
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()
# Plot forecasted energy load
plt.figure(figsize=(12,6))
plt.plot(forecast['ds_local'], forecast['yhat'], label='Forecast', color='#FF6347', linewidth=2) # Orange-ish color
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() # Show plot immediately
# Prepare the explanation text with Markdown style formatting
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 both the plot and explanation
return plt, explanation
# Step 6: Create Gradio interface
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", # You can add more themes if desired
).launch()