JavadBayazi commited on
Commit
da5122f
·
1 Parent(s): 2e328ec

Improve data fetching and add real date axes to plots

Browse files

- Switch from get_spp to get_dam_spp for full year data access
- Now fetches up to 180 days of ERCOT Day-Ahead Market prices
- Add actual calendar dates to plot axes (historical and forecast)
- Update plot styling with better formatting and date rotation
- Verify data source returns DAY_AHEAD_HOURLY market data
- Update UI labels to reflect DAM SPP data source

Files changed (1) hide show
  1. app.py +26 -20
app.py CHANGED
@@ -21,24 +21,23 @@ pipeline = load_pipeline()
21
 
22
  # Function to fetch ERCOT electricity price data
23
  @st.cache_data(ttl=3600) # Cache for 1 hour
24
- def fetch_ercot_data(days_back=160):
25
- """Fetch ERCOT day-ahead market prices for the last N days"""
26
  try:
27
  ercot = Ercot()
28
- end_date = datetime.now()
29
- start_date = end_date - timedelta(days=days_back)
30
 
31
- # Get day-ahead hourly market settlement point prices
32
- df = ercot.get_spp(
33
- date=start_date,
34
- end=end_date,
35
- market="DAY_AHEAD_HOURLY",
36
- )
37
 
38
  # Get average price per day across all locations
39
  df['Date'] = pd.to_datetime(df['Interval Start']).dt.date
40
  daily_prices = df.groupby('Date')['SPP'].mean()
41
 
 
 
 
 
42
  # Convert to comma-separated string
43
  price_list = daily_prices.round(2).tolist()
44
  return ", ".join(map(str, price_list))
@@ -84,7 +83,7 @@ else:
84
  default_data.strip(),
85
  height=150
86
  )
87
- st.info("💡 Live data from ERCOT's Day-Ahead Hourly Market - averaged across all settlement points per day")
88
 
89
  # Convert user input into a list of numbers
90
  def process_input(input_str):
@@ -101,9 +100,14 @@ prediction_length = st.slider("Select Forecast Horizon (Days)", min_value=1, max
101
 
102
  # If data is valid, perform the forecast
103
  if time_series_data:
 
 
 
 
 
104
  # Create a DataFrame for Chronos-2
105
  context_df = pd.DataFrame({
106
- 'timestamp': pd.date_range(start='2024-01-01', periods=len(time_series_data), freq='D'),
107
  'target': time_series_data,
108
  'id': 'ercot_prices'
109
  })
@@ -118,22 +122,24 @@ if time_series_data:
118
  target="target",
119
  )
120
 
121
- # Prepare forecast data for plotting
122
- forecast_index = range(len(time_series_data), len(time_series_data) + prediction_length)
123
  median = pred_df["predictions"].values
124
  low = pred_df["0.1"].values
125
  high = pred_df["0.9"].values
126
 
127
- # Plot the historical and forecasted data
128
- plt.figure(figsize=(10, 5))
129
- plt.plot(time_series_data, color="royalblue", label="Historical Prices")
130
- plt.plot(forecast_index, median, color="tomato", label="Median Forecast")
131
- plt.fill_between(forecast_index, low, high, color="tomato", alpha=0.3, label="80% Prediction Interval")
132
- plt.xlabel("Days")
133
  plt.ylabel("Price ($/MWh)")
134
  plt.title("ERCOT Electricity Price Forecast")
135
  plt.legend()
136
  plt.grid(alpha=0.3)
 
 
137
 
138
  # Show the plot in the Streamlit app
139
  st.pyplot(plt)
 
21
 
22
  # Function to fetch ERCOT electricity price data
23
  @st.cache_data(ttl=3600) # Cache for 1 hour
24
+ def fetch_ercot_data(days_back=180):
25
+ """Fetch ERCOT day-ahead market prices for the current year"""
26
  try:
27
  ercot = Ercot()
28
+ current_year = datetime.now().year
 
29
 
30
+ # Get day-ahead market settlement point prices for the year
31
+ df = ercot.get_dam_spp(year=current_year)
 
 
 
 
32
 
33
  # Get average price per day across all locations
34
  df['Date'] = pd.to_datetime(df['Interval Start']).dt.date
35
  daily_prices = df.groupby('Date')['SPP'].mean()
36
 
37
+ # Get the last N days
38
+ if len(daily_prices) > days_back:
39
+ daily_prices = daily_prices.tail(days_back)
40
+
41
  # Convert to comma-separated string
42
  price_list = daily_prices.round(2).tolist()
43
  return ", ".join(map(str, price_list))
 
83
  default_data.strip(),
84
  height=150
85
  )
86
+ st.info("💡 Live data from ERCOT's Day-Ahead Market (DAM SPP) - averaged across all settlement points per day")
87
 
88
  # Convert user input into a list of numbers
89
  def process_input(input_str):
 
100
 
101
  # If data is valid, perform the forecast
102
  if time_series_data:
103
+ # Create timestamps starting from today going backwards
104
+ end_date = datetime.now()
105
+ start_date = end_date - timedelta(days=len(time_series_data) - 1)
106
+ historical_dates = pd.date_range(start=start_date, periods=len(time_series_data), freq='D')
107
+
108
  # Create a DataFrame for Chronos-2
109
  context_df = pd.DataFrame({
110
+ 'timestamp': historical_dates,
111
  'target': time_series_data,
112
  'id': 'ercot_prices'
113
  })
 
122
  target="target",
123
  )
124
 
125
+ # Prepare forecast data for plotting with actual dates
126
+ forecast_dates = pd.date_range(start=end_date + timedelta(days=1), periods=prediction_length, freq='D')
127
  median = pred_df["predictions"].values
128
  low = pred_df["0.1"].values
129
  high = pred_df["0.9"].values
130
 
131
+ # Plot the historical and forecasted data with dates
132
+ plt.figure(figsize=(12, 6))
133
+ plt.plot(historical_dates, time_series_data, color="royalblue", label="Historical Prices", linewidth=2)
134
+ plt.plot(forecast_dates, median, color="tomato", label="Median Forecast", linewidth=2)
135
+ plt.fill_between(forecast_dates, low, high, color="tomato", alpha=0.3, label="80% Prediction Interval")
136
+ plt.xlabel("Date")
137
  plt.ylabel("Price ($/MWh)")
138
  plt.title("ERCOT Electricity Price Forecast")
139
  plt.legend()
140
  plt.grid(alpha=0.3)
141
+ plt.xticks(rotation=45)
142
+ plt.tight_layout()
143
 
144
  # Show the plot in the Streamlit app
145
  st.pyplot(plt)