Skip to content

Commit

Permalink
Improve overall experience of the app
Browse files Browse the repository at this point in the history
Merged in feature/tgi-slides (pull request PyPSA#55)

Feature/tgi slides

* Remove unused function

* Improve overall experience in app

* Improve import export display

* Add page to compare production and consumption profiles

* Add switch between production and consumption to profiles

* Add more comments
  • Loading branch information
tgi-climact committed Jul 2, 2024
1 parent a334185 commit 66ed775
Show file tree
Hide file tree
Showing 14 changed files with 421 additions and 235 deletions.
5 changes: 3 additions & 2 deletions app/VEKA_2050+.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
- **Loads**: The total yearly load per energy carrier, year, country and subsector.
- **Capacities**: The power production capacities installed per country, technologies and year.
- **RES potentials**: The total potential for RES power production capacity considered by the model for the various technologies and countries.
- **Consumption Profiles**: The load 3-hourly profiles for every carrier, year and subsector. This data is currently shown at system level (ENTSO-E area) and Belgium (BE) due to the very large quantity of data that needs to be handled for every country in the system.
- **Production Profiles**: The same visualization as consumption for the supply side: 3-hourly production profiles by carrier and year.
- **Consumption**: The yearly load and 3-hourly profiles for every carrier, year and subsector. This data is currently shown at system level (ENTSO-E area), Belgium (BE), Flanders (FL) due to the very large quantity of data that needs to be handled for every country in the system.
- **Production**: The same visualization as consumption for the supply side: yearly production and 3-hourly production profiles by carrier, year and subsector.
- **Profiles**: The same visualization of 3-hourly profiles is presented. This view enables the comparison of profiles and leads to a better understanding of the dynamics.
- **RES Profiles**: The same visualization as consumption for the supply side: 3-hourly production RES profiles by carrier and year. All countries are available.
- **Imports & Exports**: Energy imports and exports between countries in the system, for all carriers, countries and years.
- **Balancing**: (Under construction)
Expand Down
10 changes: 4 additions & 6 deletions app/pages/0Loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ def get_data(scenario):
carrier = st.selectbox('Choose your carrier:', df_ca["carrier"].unique(), index=1)
df_ca = df_ca.query("carrier==@carrier").drop("carrier", axis=1)

df_ca = df_ca.groupby(by="sector").sum()
df_ca = df_ca.groupby(by="sector").sum().sort_values(by="2050", ascending=False)

df_ca_tot = pd.DataFrame(df_ca.sum().rename("Total")).T
df_ca = pd.concat([df_ca, df_ca_tot])
df_ca.index.name = "Annual load [TWh]"

fig = px.bar(
df_ca,
Expand All @@ -69,9 +70,7 @@ def get_data(scenario):
, use_container_width=True
)

st.subheader(f"Annual load per sector for {carrier}")
st.dataframe(df_ca
.rename(mapper=lambda x: x + " [TWh]", axis=1)
.style
.format(precision=2, thousands=",", decimal='.'),
use_container_width=True
Expand Down Expand Up @@ -106,10 +105,11 @@ def get_data(scenario):
sector = st.selectbox('Choose your sector:', df_se["sector"].unique(), index=8)
df_se = df_se.query("sector==@sector").drop("sector", axis=1)

df_se = df_se.groupby(by="carrier").sum()
df_se = df_se.groupby(by="carrier").sum().sort_values(by="2050", ascending=False)

df_se_tot = pd.DataFrame(df_se.sum().rename("Total")).T
df_se = pd.concat([df_se, df_se_tot])
df_se.index.name = "Annual load [TWh]"

fig = px.bar(
df_se,
Expand All @@ -129,9 +129,7 @@ def get_data(scenario):
, use_container_width=True
)

st.subheader(f"Annual load per carrier for {sector}")
st.dataframe(df_se
.rename(mapper=lambda x: x + " [TWh]", axis=1)
.style
.format(precision=2, thousands=",", decimal='.'),
use_container_width=True
Expand Down
13 changes: 6 additions & 7 deletions app/pages/1Capacities.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def get_df(scenario):
.groupby(['sector'])
.sum(numeric_only=True)
.rename(index={"sector": "Technologies"})

)
df.index.name = "Capacity [GW]"

fig = px.bar(
df,
Expand All @@ -66,7 +66,6 @@ def get_df(scenario):
)

st.dataframe(df
.rename(mapper=lambda x: x + " [GW]", axis=1)
.style
.format(precision=2, thousands=",", decimal='.'),
use_container_width=True
Expand All @@ -85,6 +84,8 @@ def get_df(scenario):
.set_index('country')
.rename_axis("Investment year")
)
df_bar.index.name = "Capacity [GW]"

fig_bar = px.bar(
df_bar,
title=f"{technology.capitalize()} installed capacities [GW]",
Expand All @@ -99,9 +100,7 @@ def get_df(scenario):
fig_bar.update_layout(hovermode="x unified",
legend_title_text='Technologies')

col1, col2 = st.columns([0.35, 0.6])
with col1:
st.dataframe(df_bar.style.format(precision=2, thousands=",", decimal='.'), width=500)
with col2:
st.plotly_chart(fig_bar
st.plotly_chart(fig_bar
, use_container_width=True)

st.dataframe(df_bar.style.format(precision=2, thousands=",", decimal='.'), use_container_width=True)
8 changes: 8 additions & 0 deletions app/pages/1RES_Potentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def get_df(scenario):
carrier = st.multiselect('Choose your carrier:', list(df.columns.unique()), default=list(df.columns.unique())[2:4])
df = df.loc[:, carrier]
carrier_list = ' & '.join(list(map(str.capitalize, carrier)))
df.index.name = "Potential [GW]"

fig = px.bar(
df,
Expand All @@ -54,6 +55,13 @@ def get_df(scenario):
, use_container_width=True
)

st.dataframe(df
.rename(mapper=lambda x: x.capitalize() + " [GW]", axis=1)
.style
.format(precision=2, thousands=",", decimal='.'),
use_container_width=True
)

st.divider()

st.header("Potentials per country")
Expand Down
112 changes: 112 additions & 0 deletions app/pages/2Consumption.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from pathlib import Path

import pandas as pd
import plotly.express as px
import streamlit as st
from st_common import PROFILES_AREA
from st_common import YEARS
from st_common import network_path
from st_common import scenario_dict
from st_common import st_page_config
from st_common import st_side_bar

st_page_config(layout="wide")
scenario = st_side_bar()

st.title("Consumption per carrier")

st.markdown("The total energy consumption per year, country and subsector. This data is currently shown at system level (ENTSO-E area), Belgium (BE) and Flanders (FL) due to the very large quantity of data that needs to be handled for every country in the system.")


@st.cache_data(show_spinner="Retrieving data ...")
def get_data(scenario, year, selected_area):
area = selected_area if selected_area != "ENTSO-E area" else ''
return (
pd.read_csv(
Path(network_path, scenario_dict[scenario]["path"],
f"load_temporal_{area.lower()}_{year}.csv".replace('__', '_')),
header=[1, 2]
)
.set_index(("carrier", "sector"))
)


col1, col2 = st.columns(2)
with col1:
selected_area = st.selectbox('Choose area :', PROFILES_AREA)

dfx = []
for y in YEARS:
dfi = get_data(scenario, y, selected_area)
dfi = ((dfi.sum() / 1e3
* 8760 / len(dfi.axes[0]))
.to_frame(name=y))
dfx.append(dfi)
dfx = pd.concat(dfx, axis=1).fillna(0).sort_values(by=y, ascending=False)
dfx.index.name = 'Annual consumption [TWh]'

with col2:
carrier = st.selectbox('Choose your carrier:', dfx.index.unique(0).sort_values(), index=6)
dfx = dfx.loc[carrier]


st.subheader(f"Annual {carrier} consumption per sector")

total = (dfx.sum())
dfx.loc['Total'] = total
dfx.index.name = "Annual consumption [TWh]"

fig = px.bar(
dfx,
title=f"Consumption in {selected_area} for {carrier} [TWh]",
barmode="group",
text_auto=".2s"
)

fig.update_traces(hovertemplate="%{y:,.0f}")
fig.update_layout(hovermode="x unified")
fig.update_yaxes(title_text='Consumption [TWh]')
fig.update_xaxes(title_text='Sectors')
fig.update_layout(legend_title_text='Years')

st.plotly_chart(
fig
, use_container_width=True
)

st.dataframe(
dfx
.style
.format(precision=2, thousands=",", decimal='.'),
use_container_width=True
)

st.divider()


st.subheader(f"Consumption profiles per carrier")

st.markdown(
"The load 3-hourly profiles for every carrier, year and subsector. You can zoom on these interactive graphs for specific time windows and you can also select/deselect various categories if you want.")

year = st.selectbox('Choose the year:', YEARS)
data = get_data(scenario, year, selected_area)

df = data[carrier]

fig = px.area(
df,
title=f"System consumption profile for {carrier} [GW]",
)
fig.update_traces(hovertemplate="%{y:,.0f}",
line=dict(width=0.1))
fig.update_layout(legend_traceorder="reversed",
hovermode="x unified",
legend_title_text='Technologies')
fig.update_yaxes(title_text='Consumption [GW]')
fig.update_xaxes(title_text='Timesteps')

st.plotly_chart(
fig
, use_container_width=True
)
85 changes: 0 additions & 85 deletions app/pages/2Consumption_Profiles.py

This file was deleted.

Loading

0 comments on commit 66ed775

Please sign in to comment.