Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -43,13 +43,13 @@ def filter_numeric_columns(df):
|
|
| 43 |
numeric_df = df.select_dtypes(include=['number'])
|
| 44 |
return numeric_df
|
| 45 |
|
| 46 |
-
# Function to optimize the energy system
|
| 47 |
def optimize_energy_system(city_code, solar_cost, onshore_wind_cost, offshore_wind_cost, river_cost, battery_cost, yearly_demand):
|
| 48 |
# Fetch renewable energy data
|
| 49 |
data, error = get_renewable_energy_data(city_code)
|
| 50 |
if error:
|
| 51 |
st.error(error)
|
| 52 |
-
return None, None, None
|
| 53 |
|
| 54 |
# Convert all capacity factor columns to numeric, handling errors and filling missing values with zero
|
| 55 |
for col in data.columns[1:]:
|
|
@@ -164,7 +164,37 @@ def optimize_energy_system(city_code, solar_cost, onshore_wind_cost, offshore_wi
|
|
| 164 |
yaxis=dict(showgrid=True, gridwidth=0.5, gridcolor='lightgray')
|
| 165 |
)
|
| 166 |
|
| 167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
|
| 169 |
# Streamlit UI setup
|
| 170 |
st.set_page_config(page_title='Renewable Energy System Optimization', layout='wide')
|
|
@@ -176,7 +206,6 @@ st.markdown("""
|
|
| 176 |
This application is designed to help researchers and policymakers explore and optimize renewable energy systems for a specified region. By inputting cost parameters for different renewable energy sources and energy storage systems, the application determines the optimal mix of resources to meet energy demand while minimizing cost.
|
| 177 |
The optimization problem is solved using linear programming, ensuring a balance between supply and demand, and incorporating battery energy storage to manage intermittency issues inherent in renewable energy.
|
| 178 |
The visualizations provided help to better understand how different energy sources contribute to the overall power supply, how energy storage systems are utilized, and the impact of cost variations on energy prices.
|
| 179 |
-
|
| 180 |
""")
|
| 181 |
|
| 182 |
# Sidebar input fields for user to provide parameters
|
|
@@ -192,11 +221,16 @@ with st.sidebar:
|
|
| 192 |
|
| 193 |
# Button to trigger optimization
|
| 194 |
if st.button('Calculate Optimal Energy Mix'):
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
|
| 199 |
-
# Additional analysis and visualizations
|
| 200 |
st.markdown("### Additional Analysis")
|
| 201 |
st.markdown("The following plots provide additional insights into the renewable energy mix, curtailment, and electricity price variations.")
|
| 202 |
|
|
@@ -213,47 +247,11 @@ if st.button('Calculate Optimal Energy Mix'):
|
|
| 213 |
st.plotly_chart(fig_cost, use_container_width=True, height=800)
|
| 214 |
|
| 215 |
# Plot curtailment over time
|
| 216 |
-
curtailment_df = pd.DataFrame({"Time":
|
| 217 |
fig_curtailment = px.line(curtailment_df, x='Time', y='Curtailment (MW)', title='Curtailment Over Time', template='plotly_white')
|
| 218 |
st.plotly_chart(fig_curtailment, use_container_width=True, height=800)
|
| 219 |
|
| 220 |
# Plot electricity price variation over time
|
| 221 |
-
price_df = pd.DataFrame({"Time":
|
| 222 |
fig_price = px.line(price_df, x='Time', y='Electricity Price (¥/MWh)', title='Electricity Price Variation Over Time', template='plotly_white')
|
| 223 |
st.plotly_chart(fig_price, use_container_width=True, height=800)
|
| 224 |
-
|
| 225 |
-
# Correlation analysis between renewable energy sources
|
| 226 |
-
if city_code:
|
| 227 |
-
st.markdown("### Correlation Between Renewable Energy Sources")
|
| 228 |
-
energy_data_df, error = get_renewable_energy_data(city_code)
|
| 229 |
-
if error:
|
| 230 |
-
st.error(error)
|
| 231 |
-
else:
|
| 232 |
-
numeric_energy_data_df = filter_numeric_columns(energy_data_df)
|
| 233 |
-
|
| 234 |
-
numeric_energy_data_df = numeric_energy_data_df.fillna(0)
|
| 235 |
-
|
| 236 |
-
correlation_matrix = numeric_energy_data_df.corr()
|
| 237 |
-
|
| 238 |
-
if correlation_matrix is not None:
|
| 239 |
-
fig_corr = px.imshow(correlation_matrix, title='Correlation Matrix of Renewable Capacity Factors', labels={'color': 'Correlation'}, template='plotly_white')
|
| 240 |
-
st.plotly_chart(fig_corr, use_container_width=True, height=800)
|
| 241 |
-
|
| 242 |
-
# Heatmap of renewable energy and demand characteristics
|
| 243 |
-
st.markdown("### Heatmap of Renewable Energy and Demand Characteristics")
|
| 244 |
-
hourly_data = numeric_energy_data_df.copy()
|
| 245 |
-
hourly_data['Time'] = pd.to_datetime(energy_data_df['Time'], errors='coerce')
|
| 246 |
-
hourly_data['Date'] = hourly_data['Time'].dt.strftime('%j').astype(int) # Convert to day of year (1-365)
|
| 247 |
-
hourly_data['Hour'] = hourly_data['Time'].dt.hour
|
| 248 |
-
|
| 249 |
-
for column in hourly_data.columns[2:]:
|
| 250 |
-
# Create a pivot table to reshape data into hours of the day vs days of the year
|
| 251 |
-
pivot_df = hourly_data.pivot_table(index='Hour', columns='Date', values=column, aggfunc=np.mean)
|
| 252 |
-
# Plot using seaborn to create a heatmap similar to the provided image
|
| 253 |
-
plt.figure(figsize=(12, 6))
|
| 254 |
-
sns.heatmap(pivot_df, cmap='viridis', cbar_kws={'label': f'{column} (kW)'})
|
| 255 |
-
plt.title(f'Heatmap of {column}')
|
| 256 |
-
plt.xlabel('Days of the Year')
|
| 257 |
-
plt.ylabel('Hours of the Day')
|
| 258 |
-
st.pyplot(plt.gcf())
|
| 259 |
-
plt.close()
|
|
|
|
| 43 |
numeric_df = df.select_dtypes(include=['number'])
|
| 44 |
return numeric_df
|
| 45 |
|
| 46 |
+
# Function to optimize the energy system and create heatmaps
|
| 47 |
def optimize_energy_system(city_code, solar_cost, onshore_wind_cost, offshore_wind_cost, river_cost, battery_cost, yearly_demand):
|
| 48 |
# Fetch renewable energy data
|
| 49 |
data, error = get_renewable_energy_data(city_code)
|
| 50 |
if error:
|
| 51 |
st.error(error)
|
| 52 |
+
return None, None, None, None
|
| 53 |
|
| 54 |
# Convert all capacity factor columns to numeric, handling errors and filling missing values with zero
|
| 55 |
for col in data.columns[1:]:
|
|
|
|
| 164 |
yaxis=dict(showgrid=True, gridwidth=0.5, gridcolor='lightgray')
|
| 165 |
)
|
| 166 |
|
| 167 |
+
# Create a heatmap for each energy source (solar, onshore wind, offshore wind, river)
|
| 168 |
+
heatmaps = []
|
| 169 |
+
for energy_source in ['solar', 'onshore_wind', 'offshore_wind', 'river']:
|
| 170 |
+
df_heatmap = data[['Time', f'{energy_source} hourly capacity factor']].copy()
|
| 171 |
+
df_heatmap['day_of_year'] = df_heatmap['Time'].dt.dayofyear
|
| 172 |
+
df_heatmap['hour_of_day'] = df_heatmap['Time'].dt.hour
|
| 173 |
+
|
| 174 |
+
# Pivot the data for heatmap
|
| 175 |
+
pivot_df = df_heatmap.pivot(index='hour_of_day', columns='day_of_year', values=f'{energy_source} hourly capacity factor')
|
| 176 |
+
|
| 177 |
+
# Create Plotly heatmap
|
| 178 |
+
fig_heatmap = px.imshow(
|
| 179 |
+
pivot_df.values,
|
| 180 |
+
labels=dict(x="Day of Year", y="Hour of Day", color=f"{energy_source.replace('_', ' ').title()} Capacity Factor"),
|
| 181 |
+
x=pivot_df.columns,
|
| 182 |
+
y=pivot_df.index,
|
| 183 |
+
aspect="auto",
|
| 184 |
+
color_continuous_scale='Plasma'
|
| 185 |
+
)
|
| 186 |
+
|
| 187 |
+
fig_heatmap.update_layout(
|
| 188 |
+
title=f'{energy_source.replace("_", " ").title()} Hourly Capacity Factor (24 Hours x 365 Days)',
|
| 189 |
+
xaxis_title='Day of Year',
|
| 190 |
+
yaxis_title='Hour of Day',
|
| 191 |
+
font=dict(size=12),
|
| 192 |
+
plot_bgcolor='white',
|
| 193 |
+
margin=dict(l=40, r=40, t=40, b=40),
|
| 194 |
+
)
|
| 195 |
+
heatmaps.append(fig_heatmap)
|
| 196 |
+
|
| 197 |
+
return fig_energy, heatmaps, curtailment_values, price_per_hour
|
| 198 |
|
| 199 |
# Streamlit UI setup
|
| 200 |
st.set_page_config(page_title='Renewable Energy System Optimization', layout='wide')
|
|
|
|
| 206 |
This application is designed to help researchers and policymakers explore and optimize renewable energy systems for a specified region. By inputting cost parameters for different renewable energy sources and energy storage systems, the application determines the optimal mix of resources to meet energy demand while minimizing cost.
|
| 207 |
The optimization problem is solved using linear programming, ensuring a balance between supply and demand, and incorporating battery energy storage to manage intermittency issues inherent in renewable energy.
|
| 208 |
The visualizations provided help to better understand how different energy sources contribute to the overall power supply, how energy storage systems are utilized, and the impact of cost variations on energy prices.
|
|
|
|
| 209 |
""")
|
| 210 |
|
| 211 |
# Sidebar input fields for user to provide parameters
|
|
|
|
| 221 |
|
| 222 |
# Button to trigger optimization
|
| 223 |
if st.button('Calculate Optimal Energy Mix'):
|
| 224 |
+
fig_energy, heatmaps, curtailment_values, price_per_hour = optimize_energy_system(city_code, solar_cost, onshore_wind_cost, offshore_wind_cost, river_cost, battery_cost, yearly_demand)
|
| 225 |
+
|
| 226 |
+
if fig_energy:
|
| 227 |
+
st.plotly_chart(fig_energy, use_container_width=True, height=800)
|
| 228 |
+
|
| 229 |
+
# Additional visualizations
|
| 230 |
+
st.markdown("### Hourly Capacity Factor Heatmaps")
|
| 231 |
+
for fig_heatmap in heatmaps:
|
| 232 |
+
st.plotly_chart(fig_heatmap, use_container_width=True, height=800)
|
| 233 |
|
|
|
|
| 234 |
st.markdown("### Additional Analysis")
|
| 235 |
st.markdown("The following plots provide additional insights into the renewable energy mix, curtailment, and electricity price variations.")
|
| 236 |
|
|
|
|
| 247 |
st.plotly_chart(fig_cost, use_container_width=True, height=800)
|
| 248 |
|
| 249 |
# Plot curtailment over time
|
| 250 |
+
curtailment_df = pd.DataFrame({"Time": fig_energy.data[0].x, "Curtailment (MW)": curtailment_values})
|
| 251 |
fig_curtailment = px.line(curtailment_df, x='Time', y='Curtailment (MW)', title='Curtailment Over Time', template='plotly_white')
|
| 252 |
st.plotly_chart(fig_curtailment, use_container_width=True, height=800)
|
| 253 |
|
| 254 |
# Plot electricity price variation over time
|
| 255 |
+
price_df = pd.DataFrame({"Time": fig_energy.data[0].x, "Electricity Price (¥/MWh)": price_per_hour})
|
| 256 |
fig_price = px.line(price_df, x='Time', y='Electricity Price (¥/MWh)', title='Electricity Price Variation Over Time', template='plotly_white')
|
| 257 |
st.plotly_chart(fig_price, use_container_width=True, height=800)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|