From eb6553d5a09f96e48d8fbc13e9586a3998289e21 Mon Sep 17 00:00:00 2001 From: "j.aschauer" Date: Thu, 30 Nov 2023 10:50:49 +0100 Subject: [PATCH 1/5] add possibility to override session state in `calculate_results_list` --- app/ptxboa_functions.py | 49 ++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/app/ptxboa_functions.py b/app/ptxboa_functions.py index 0d023c56..89cd3412 100644 --- a/app/ptxboa_functions.py +++ b/app/ptxboa_functions.py @@ -38,35 +38,33 @@ def calculate_results_list( api: PtxboaAPI, parameter_to_change: str, parameter_list: list = None, + override_session_state: dict | None = None, ) -> pd.DataFrame: """Calculate results for source regions and one selected target country. Parameters ---------- - _api : :class:`~ptxboa.api.PtxboaAPI` + api : :class:`~ptxboa.api.PtxboaAPI` an instance of the api class - settings : dict - settings from the streamlit app. An example can be obtained with the - return value from :func:`ptxboa_functions.create_sidebar`. parameter_to_change : str element of settings for which a list of values is to be used. parameter_list : list or None The values of ``parameter_to_change`` for which the results are calculated. If None, all values available in the API will be used. + override_session_state : dict or None + pass a dict with custom values in order to change the calculation parameters + obtained from st.session_state. I None, all parameters are taken from the + session state. Keys of the dictionary must in "chain", "country", + "output_unit", "region", "res_gen", "scenario", "secproc_co2", + "secproc_water", "ship_own_fuel", "transport". Returns ------- pd.DataFrame - same format as for :meth:`~ptxboa.api.PtxboaAPI.calculate()` + wide format dataframe with index values from `parameter_to_change` and columns + containing the different cost components and a column for total costs "Total". """ - res_list = [] - - if parameter_list is None: - parameter_list = api.get_dimension(parameter_to_change).index - - # copy settings from session_state: - settings = {} - for key in [ + setting_keys = [ "chain", "country", "output_unit", @@ -77,15 +75,30 @@ def calculate_results_list( "secproc_water", "ship_own_fuel", "transport", - ]: - settings[key] = st.session_state[key] + ] + + # copy settings from session_state: + settings = {key: st.session_state[key] for key in setting_keys} + + # update settings from session state with custom values + if override_session_state is not None: + if not set(override_session_state.keys()).issubset(set(setting_keys)): + msg = ( + f"keys in 'override_session_state' must be in dict_keys({setting_keys})" + f" but are currently {override_session_state.keys()}" + ) + raise ValueError(msg) + settings.update(override_session_state) + if parameter_list is None: + parameter_list = api.get_dimension(parameter_to_change).index + + res_list = [] for parameter in parameter_list: - settings2 = settings.copy() - settings2[parameter_to_change] = parameter + settings.update({parameter_to_change: parameter}) res_single = calculate_results_single( api, - settings2, + settings, user_data=st.session_state["user_changes_df"], ) res_list.append(res_single) From 250eaf32bc135fe01a38b8793926d6a8de51c472 Mon Sep 17 00:00:00 2001 From: "j.aschauer" Date: Thu, 30 Nov 2023 10:51:51 +0100 Subject: [PATCH 2/5] add option to pass output unit to `dislay_costs` --- app/layout_elements.py | 7 ++++++- app/plot_functions.py | 14 ++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/layout_elements.py b/app/layout_elements.py index bbdc4ce0..3912c713 100644 --- a/app/layout_elements.py +++ b/app/layout_elements.py @@ -8,7 +8,11 @@ def display_costs( - df_costs: pd.DataFrame, key: str, titlestring: str, key_suffix: str = "" + df_costs: pd.DataFrame, + key: str, + titlestring: str, + key_suffix: str = "", + output_unit: str | None = None, ): """Display costs as table and bar chart.""" key_suffix = key_suffix.lower().replace(" ", "_") @@ -49,6 +53,7 @@ def display_costs( fig = create_bar_chart_costs( df_res, current_selection=st.session_state[key], + output_unit=output_unit, ) st.plotly_chart(fig, use_container_width=True) diff --git a/app/plot_functions.py b/app/plot_functions.py index 207ed705..c8f05953 100644 --- a/app/plot_functions.py +++ b/app/plot_functions.py @@ -348,7 +348,11 @@ def _make_costs_hoverdata(res_costs: pd.DataFrame) -> list[pd.Series]: return [custom_hover_data] -def create_bar_chart_costs(res_costs: pd.DataFrame, current_selection: str = None): +def create_bar_chart_costs( + res_costs: pd.DataFrame, + current_selection: str = None, + output_unit: str | None = None, +): """Create bar plot for costs by components, and dots for total costs. Parameters @@ -404,9 +408,11 @@ def create_bar_chart_costs(res_costs: pd.DataFrame, current_selection: str = Non ax=0, ay=-50, ) - fig.update_layout( - yaxis_title=st.session_state["output_unit"], - ) + + if output_unit is None: + output_unit = st.session_state["output_unit"] + + fig.update_layout(yaxis_title=output_unit) return fig From 9a0cf688cb2db1f55e895ecad31670fdb46431c4 Mon Sep 17 00:00:00 2001 From: "j.aschauer" Date: Thu, 30 Nov 2023 10:53:04 +0100 Subject: [PATCH 3/5] always use "USD/MWh" as unit for supply chain comparison (#149) --- app/tab_dashboard.py | 4 +++- ptxboa_streamlit.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/tab_dashboard.py b/app/tab_dashboard.py index 768813b6..a4b42313 100644 --- a/app/tab_dashboard.py +++ b/app/tab_dashboard.py @@ -98,4 +98,6 @@ def content_dashboard( costs_per_res_gen, "res_gen", "Costs by renewable electricity source:" ) - display_costs(costs_per_chain, "chain", "Costs by supply chain:") + display_costs( + costs_per_chain, "chain", "Costs by supply chain:", output_unit="USD/MWh" + ) diff --git a/ptxboa_streamlit.py b/ptxboa_streamlit.py index f59e0868..87ec43a8 100644 --- a/ptxboa_streamlit.py +++ b/ptxboa_streamlit.py @@ -116,6 +116,7 @@ api, parameter_to_change="chain", parameter_list=None, + override_session_state={"output_unit": "USD/MWh"}, ) # import context data: From 09c5e842af043d6f981924454bcf4a10f7ba1395 Mon Sep 17 00:00:00 2001 From: "j.aschauer" Date: Wed, 6 Dec 2023 09:33:38 +0100 Subject: [PATCH 4/5] show selected output unit also in data, fix missed change from merge commit --- app/layout_elements.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/layout_elements.py b/app/layout_elements.py index cb1bd36e..afb5e8a9 100644 --- a/app/layout_elements.py +++ b/app/layout_elements.py @@ -52,12 +52,11 @@ def display_costs( fig = create_bar_chart_costs( df_res, current_selection=st.session_state[key], + output_unit=output_unit, ) st.plotly_chart(fig, use_container_width=True) with st.expander("**Data**"): - column_config = config_number_columns( - df_res, format=f"%.1f {st.session_state['output_unit']}" - ) + column_config = config_number_columns(df_res, format=f"%.1f {output_unit}") st.dataframe(df_res, use_container_width=True, column_config=column_config) return None From 82de6283325b361d47f93de576af559617aa8fe5 Mon Sep 17 00:00:00 2001 From: "j.aschauer" Date: Wed, 6 Dec 2023 09:36:10 +0100 Subject: [PATCH 5/5] fallback to session state output unit if it is None in display costs --- app/layout_elements.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/layout_elements.py b/app/layout_elements.py index afb5e8a9..509363fa 100644 --- a/app/layout_elements.py +++ b/app/layout_elements.py @@ -15,6 +15,8 @@ def display_costs( output_unit: str | None = None, ): """Display costs as table and bar chart.""" + if output_unit is None: + output_unit = st.session_state["output_unit"] key_suffix = key_suffix.lower().replace(" ", "_") st.subheader(titlestring)