Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

137 improve market scanning tab #210

Merged
merged 12 commits into from
Dec 14, 2023
214 changes: 188 additions & 26 deletions app/tab_market_scanning.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
import plotly.express as px
import streamlit as st

from app.ptxboa_functions import config_number_columns, remove_subregions
from app.ptxboa_functions import (
config_number_columns,
prepare_and_download_df_as_excel,
remove_subregions,
)
from ptxboa.api import PtxboaAPI


def content_market_scanning(api: PtxboaAPI, res_costs: pd.DataFrame) -> None:
def content_market_scanning(api: PtxboaAPI, res_costs: pd.DataFrame, cd: dict) -> None:
"""Create content for the "market scanning" sheet.

Parameters
Expand All @@ -17,6 +21,8 @@ def content_market_scanning(api: PtxboaAPI, res_costs: pd.DataFrame) -> None:
an instance of the api class
res_costs : pd.DataFrame
Results.
cd: dict
context data.
"""
with st.expander("What is this?"):
st.markdown(
Expand Down Expand Up @@ -47,39 +53,195 @@ def content_market_scanning(api: PtxboaAPI, res_costs: pd.DataFrame) -> None:
)

# merge costs and distances:
df_plot = pd.DataFrame()
df_plot["total costs"] = res_costs["Total"]
df_plot = df_plot.merge(distances, left_index=True, right_index=True)
df = pd.DataFrame()
df["total costs"] = res_costs["Total"]
df = df.merge(distances, left_index=True, right_index=True)

# merge RE supply potential from context data:
df = df.merge(
cd["supply"].set_index("country_name")[
["re_tech_pot_EWI", "re_tech_pot_PTXAtlas"]
],
left_index=True,
right_index=True,
how="left",
)

# prettify column names:
df.rename(
{
"total costs": f"Total costs ({st.session_state['output_unit']})",
"shipping distance": "Shipping distance (km)",
"pipeline distance": "Pipeline distance (km)",
"re_tech_pot_EWI": "RE technical potential (EWI) (TWh/a)",
"re_tech_pot_PTXAtlas": "RE technical potential (PTX Atlas) (TWh/a)",
},
inplace=True,
axis=1,
)

# replace nan entries:
df = df.replace({"no potential": None, "no analysis ": None})
df = df.astype(float)

# do not show subregions:
df_plot = remove_subregions(api, df_plot, st.session_state["country"])
df = remove_subregions(api, df, st.session_state["country"])

with st.container(border=True):
st.markdown(
"### Costs and transportation distances from different supply regions"
f" to {st.session_state['country']}"
)
c1, c2 = st.columns(2)
with c1:
# select which distance to show:
selected_distance = st.radio(
"Select parameter to show on horizontal axis:",
["Shipping distance (km)", "Pipeline distance (km)"],
key="selected_distance_supply_regions",
)

# create plot:st.session_state
[c1, c2] = st.columns([1, 5])
with c1:
# select which distance to show:
with c2:
# select parameter for marker size:
parameter_for_marker_size = st.radio(
"Select parameter to scale marker size:",
[
"RE technical potential (EWI) (TWh/a)",
"RE technical potential (PTX Atlas) (TWh/a)",
"None",
],
)

# create plot:
df_plot = df.copy().round(0)

# distinguish between selected region and others:
df_plot["category"] = "other regions"
df_plot.at[st.session_state["region"], "category"] = "selected supply region"

if parameter_for_marker_size == "None":
fig = px.scatter(
df_plot,
x=selected_distance,
y=f"Total costs ({st.session_state['output_unit']})",
color="category",
color_discrete_sequence=["#1A667B", "#D05094"],
text=df_plot.index,
)
fig.update_traces(textposition="top center")
else:
df_plot = df_plot.loc[df_plot[parameter_for_marker_size] > 0]
fig = px.scatter(
df_plot,
x=selected_distance,
y=f"Total costs ({st.session_state['output_unit']})",
size=parameter_for_marker_size,
size_max=50,
color="category",
color_discrete_sequence=["#1A667B", "#D05094"],
text=df_plot.index,
)
fig.update_traces(textposition="top center")

st.plotly_chart(fig, use_container_width=True)

# show data in tabular form:
with st.expander("**Data**"):
column_config = config_number_columns(df, format="%.0f")
st.dataframe(
df,
use_container_width=True,
column_config=column_config,
)

fn = "market_scanning_supply_regions"
prepare_and_download_df_as_excel(df, filename=fn)

with st.container(border=True):
st.markdown(
f"### Transportation distances from {st.session_state['region']}"
" to different target countries"
)

# filter shipping and pipeline distances:
df = input_data.loc[
(
input_data["parameter_code"].isin(
["shipping distance", "pipeline distance"]
)
)
& (input_data["source_region_code"] == st.session_state["region"]),
["target_country_code", "parameter_code", "value"],
]
df = df.pivot_table(
index="target_country_code",
columns="parameter_code",
values="value",
aggfunc="sum",
)

# merge H2 demand from context data:

# H2 demand data hard coded from excel tool.
# TODO: improve data representation in context_data.xlsx
# and take data from there.
df["h2_demand_2030"] = None

df.at["China", "h2_demand_2030"] = 35
df.at["France", "h2_demand_2030"] = None
df.at["Germany", "h2_demand_2030"] = 3
df.at["India", "h2_demand_2030"] = 10
df.at["Japan", "h2_demand_2030"] = 3
df.at["Netherlands", "h2_demand_2030"] = None
df.at["South Korea", "h2_demand_2030"] = 2
df.at["Spain", "h2_demand_2030"] = None
df.at["USA", "h2_demand_2030"] = 10

# EU data is missing completely in context_data.xlsx:
df.at["EU", "shipping distance"] = 1104
df.at["EU", "pipeline distance"] = 2000
df.at["EU", "h2_demand_2030"] = 20

df["h2_demand_2030"] = df["h2_demand_2030"].astype(float)

# prettify column names:
df.rename(
{
"shipping distance": "Shipping distance (km)",
"pipeline distance": "Pipeline distance (km)",
"h2_demand_2030": "Projected H2 demand in 2030 (Mt/a)",
},
inplace=True,
axis=1,
)

# select parameter to display on x axis:
selected_distance = st.radio(
"Select parameter:",
["shipping distance", "pipeline distance"],
"Select parameter to show on horizontal axis:",
["Shipping distance (km)", "Pipeline distance (km)"],
key="selected_distance_target_countries",
)
with c2:

# create plot:
df_plot = df.copy().round(0)

# distinguish between selected region and others:
df_plot["category"] = "other countries"
df_plot.at[st.session_state["country"], "category"] = "selected target country"

fig = px.scatter(
df_plot,
x=selected_distance,
y="total costs",
title="Costs and transportation distances",
height=600,
)
# Add text above markers
fig.update_traces(
y="Projected H2 demand in 2030 (Mt/a)",
color="category",
color_discrete_sequence=["#1A667B", "#D05094"],
text=df_plot.index,
textposition="top center",
mode="markers+text",
)
fig.update_traces(textposition="top center")

st.plotly_chart(fig)
st.plotly_chart(fig, use_container_width=True)

# show data in tabular form:
st.markdown("**Data:**")
column_config = config_number_columns(df_plot, format="%.1f")
st.dataframe(df_plot, use_container_width=True, column_config=column_config)
with st.expander("**Data**"):
st.dataframe(df, use_container_width=True)
fn = "market_scanning_target_countries"
prepare_and_download_df_as_excel(df, filename=fn)
11 changes: 8 additions & 3 deletions ptxboa_streamlit.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# -*- coding: utf-8 -*-
"""Mockup streamlit app."""
"""
PtX BOA streamlit app, main file.

Execution:
>>> streamlit run ptxboa_streamlit.py
"""
# TODO how do I use the treamlit logger?
import logging

Expand Down Expand Up @@ -39,7 +44,7 @@
logger.addHandler(log_handler)


logger.info("Updating app...")
logger.debug("Updating app...")

# app layout:

Expand Down Expand Up @@ -191,7 +196,7 @@
)

if st.session_state[st.session_state["tab_key"]] == "Market scanning":
content_market_scanning(api, costs_per_region)
content_market_scanning(api, costs_per_region, cd)

if st.session_state[st.session_state["tab_key"]] == "Input data":
content_input_data(api)
Expand Down