Spaces:
Sleeping
Sleeping
File size: 7,551 Bytes
724eb6a 4ca4a1a |
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# Import gradio
import gradio as gr
# Data import from open-meteo.com
import openmeteo_requests
import requests_cache
from retry_requests import retry
# Data management and visualization
import pandas as pd
import numpy as np
import datetime
import pickle
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# Machine Learning
import sklearn
# Print version info
print("Version info:")
print('pandas: %s' % pd.__version__)
print('numpy: %s' % np.__version__)
print('sklearn: %s' % sklearn.__version__)
print(" ")
def makeprediction():
#%% 1. User Inputs
# These inputs may be changed by the user
model_file_name = "Solar RF Model_2024-01-03T08-53-53_.pkl" # This is the name of the file generated by the script "Build_solar_RF_model.py" (must be located in same folder)
horizon = 2 # Forecast horizon in days, limit is 16 days.
# Note that the further we look into the future, the less accurate the weather forecast is likely to be
PV_capacity = 15 # The maximum capacity of your PV installation in kW, only used for plotting.
#%% 2. Read Model
# Read in the model
f_model = open(model_file_name, 'rb') # Opens the file
model_dict = pickle.load(f_model) # Reads the dictionary from the file
f_model.close() # closes the file again
#%% 3. Fetch weather forecast
# Setup the Open-Meteo API client with cache and retry on error
cache_session = requests_cache.CachedSession('.cache', expire_after = -1)
retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2)
openmeteo = openmeteo_requests.Client(session = retry_session)
# Make sure all required weather variables are listed here
url = "https://api.open-meteo.com/v1/forecast"
# Calcualte start and end date
start_date = datetime.datetime.now()
end_date = start_date + datetime.timedelta(days=horizon)
sdate_str = str(start_date)[0:10] # First date in file as string (yyyy-mm-dd)
edate_str = str(end_date)[0:10] # Last date in file as string (yyyy-mm-dd)
# Use the same parameters as was used for training the model.
params = {
"latitude": model_dict['API Request Params']['latitude'],
"longitude": model_dict['API Request Params']['longitude'],
"hourly": model_dict['API Request Params']['hourly'],
"start_date": sdate_str,
"end_date": edate_str,
}
responses = openmeteo.weather_api(url, params=params)
# Process & print request info.
response = responses[0]
print("Request info:")
print(f"Coordinates {response.Latitude()}°E {response.Longitude()}°N")
print(f"Elevation {response.Elevation()} m asl")
print(f"Timezone {response.Timezone()} {response.TimezoneAbbreviation()}")
print(f"Timezone difference to GMT+0 {response.UtcOffsetSeconds()} s")
#print(f"From: " + sdate_str + " To: " + edate_str)
print(" ")
# Process hourly data. The order of variables needs to be the same as requested.
hourly = response.Hourly() # API Response
hourly_data = {"date": pd.date_range( # Dictionary that we add the API respnse to
start = pd.to_datetime(hourly.Time(), unit = "s"),
end = pd.to_datetime(hourly.TimeEnd(), unit = "s"),
freq = pd.Timedelta(seconds = hourly.Interval()),
inclusive = "left"
)}
# We iterate through the variables and add the API response data to our dictionary
print("Adding variables to dataframe...")
index_variable = 0
for variable in params['hourly']:
hourly_data[variable] = hourly.Variables(index_variable).ValuesAsNumpy() # Add the variable to dataframe
print("Added " + variable)
index_variable += 1 # Increment counter
print(" ")
# Create dataframe
weather_data = pd.DataFrame(data = hourly_data)
weather_data = weather_data.set_index('date') # Set index to be dates
#%% 4. Data manipulation & encoding
# Create a new dataframe to hold all data, also encode new features.
# Create a main dataframe that holds all data
main_df = weather_data.copy()
for index, row in main_df.iterrows():
main_df.loc[index,'month'] = index.month
main_df.loc[index,'day'] = index.day
main_df.loc[index,'hour'] = index.hour
main_df.loc[index,'sine month'] = np.sin((index.month - 1)*np.pi/11)
main_df.loc[index,'cos month'] = np.cos((index.month - 1)*np.pi/11)
main_df.loc[index,'sine hour'] = np.sin((index.month - 1)*np.pi/23)
main_df.loc[index,'cos hour'] = np.cos((index.month - 1)*np.pi/23)
# Index to keep track of which hours the sun is up for.
Sun_index = main_df[main_df['is_day'] == 1].index
# Create a new dataframe with only relevant data, this will be used for statistical
sun_is_up_data = main_df.copy() # Create copy
sun_is_up_data = sun_is_up_data.loc[Sun_index] # Only include rows when the sun is up
sun_is_up_data = sun_is_up_data[model_dict['Input features']] # Only include columns needed for model
#%% 5. Make Predictions
print("Making predictions...")
# Create dataframe to hold predictions and initialize with 0.
predictions = pd.DataFrame(0, index = weather_data.index, columns = ['Main Forecast', 'Lower Bound', 'Upper Bound'])
predictions['Date'] = predictions.index.tolist() # Make dates also to a column for easier plotting
# Make predictions
predictions.loc[Sun_index,'Main Forecast'] = model_dict['Random Forest Model'].predict(sun_is_up_data)
predictions.loc[Sun_index,['Lower Bound', 'Upper Bound']] = model_dict['Random Forest Quantile Model'].predict(sun_is_up_data, quantiles=[0.1, 0.9], interpolation='linear')
print(" ")
#%% 6. Make Plot
# Plotting
plt.style.use('_mpl-gallery') # Set plot style
matplotlib.rc('font', **{'size' : 20}) # Change font size
fig, ax = plt.subplots() # Create plot
fig.set_size_inches(18.5, 10.5, forward=True) # Set figure size
fig.set_dpi(100) # Set resolution
ax.fill_between(predictions['Date'], predictions['Lower Bound'], predictions['Upper Bound'], alpha=.5, linewidth=0) # Plot prediction interval
ax.plot(predictions['Date'], predictions['Main Forecast'], linewidth=4, color='black') # Plot main forecast
# Calculate x-ticks
step_length = int(predictions.shape[0]/32)
ax.set(ylim = [0,PV_capacity*1.05], xticks = predictions['Date'].iloc[::step_length])
ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M'))
plt.ylabel('Solar power [kW]')
plt.xticks(rotation=90)
plt.legend(['Prediction Interval (10 - 90%)', 'Main Forecast'])
plt.title('Solar Power Forecast from ' + sdate_str + ' to ' + edate_str)
# plt.show()
return fig
def greet(name):
return "Hello " + name + "!!"
iface = gr.Interface(fn=makeprediction, inputs=None, outputs=gr.Plot())
iface.launch() |