From 2b40b0b916a1f1f170a934a9cc5337ea204cf971 Mon Sep 17 00:00:00 2001 From: Markus Haller Date: Wed, 8 Nov 2023 15:07:11 +0100 Subject: [PATCH 1/4] improve number format in data tables (#70) --- app/ptxboa_functions.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/ptxboa_functions.py b/app/ptxboa_functions.py index a4b7c33d..02f13ffa 100644 --- a/app/ptxboa_functions.py +++ b/app/ptxboa_functions.py @@ -464,7 +464,7 @@ def content_market_scanning( # show data in tabular form: st.markdown("**Data:**") - st.dataframe(df_plot, use_container_width=True) + st.dataframe(df_plot.style.format(precision=2), use_container_width=True) def remove_subregions(api: PtxboaAPI, df: pd.DataFrame, settings: dict): @@ -554,7 +554,7 @@ def content_costs_by_region( create_bar_chart_costs(df_res) st.write("**Data:**") - st.dataframe(df_res, use_container_width=True) + st.dataframe(df_res.style.format(precision=2), use_container_width=True) def content_deep_dive_countries( @@ -765,18 +765,29 @@ def display_and_edit_data_table( df = input_data.loc[ind1 & ind2 & ind3] df_tab = df.pivot_table(index=index, columns=columns, values=values, aggfunc="sum") + # if editing is enabled, store modifications in session_state: if st.session_state["edit_input_data"]: disabled = [index] key = f"edit_input_data_{parameter_code}" else: disabled = True key = None + + # configure columns for display: + column_config = {} + for c in df_tab.columns: + column_config[c] = st.column_config.NumberColumn( + format="%.2f", + ) + + # display data: st.data_editor( - df_tab, + df_tab.style.format(precision=2), use_container_width=True, key=key, num_rows="fixed", disabled=disabled, + column_config=column_config, ) # store changes in session_state: From e61014ccea69023c4c5929510b423ba12803b41f Mon Sep 17 00:00:00 2001 From: Markus Haller Date: Wed, 8 Nov 2023 16:04:52 +0100 Subject: [PATCH 2/4] improve number formatting --- app/ptxboa_functions.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/app/ptxboa_functions.py b/app/ptxboa_functions.py index 02f13ffa..0ad3b2ec 100644 --- a/app/ptxboa_functions.py +++ b/app/ptxboa_functions.py @@ -701,6 +701,9 @@ def content_input_data(api: PtxboaAPI, settings: dict) -> None: "Wind-PV-Hybrid", ] x = "process_code" + column_config = st.column_config.NumberColumn( + format="%.0f USD/kW", + ) if data_selection == "full load hours": parameter_code = ["full load hours"] process_code = [ @@ -710,10 +713,16 @@ def content_input_data(api: PtxboaAPI, settings: dict) -> None: "Wind-PV-Hybrid", ] x = "process_code" + column_config = st.column_config.NumberColumn( + format="%.0f h/a", + ) if data_selection == "interest rate": parameter_code = ["interest rate"] process_code = [""] x = "parameter_code" + column_config = st.column_config.NumberColumn( + format="%.3f", + ) c1, c2 = st.columns(2, gap="medium") with c2: @@ -725,7 +734,9 @@ def content_input_data(api: PtxboaAPI, settings: dict) -> None: source_region_code=region_list_without_subregions, parameter_code=parameter_code, process_code=process_code, + column_config=column_config, ) + with c1: # create plot: st.markdown("**Figure:**") @@ -757,6 +768,7 @@ def display_and_edit_data_table( index: str = "source_region_code", columns: str = "process_code", values: str = "value", + column_config=None, ) -> pd.DataFrame: """Display selected input data as 2D table, which can also be edited.""" ind1 = input_data["source_region_code"].isin(source_region_code) @@ -774,11 +786,14 @@ def display_and_edit_data_table( key = None # configure columns for display: - column_config = {} + column_config_all = {} for c in df_tab.columns: - column_config[c] = st.column_config.NumberColumn( - format="%.2f", - ) + if column_config is not None: + column_config_all[c] = column_config + else: + column_config_all[c] = st.column_config.NumberColumn( + format="%.2f", + ) # display data: st.data_editor( @@ -787,8 +802,10 @@ def display_and_edit_data_table( key=key, num_rows="fixed", disabled=disabled, - column_config=column_config, + column_config=column_config_all, ) + if st.session_state["edit_input_data"]: + st.markdown("You can edit data directly in the table!") # store changes in session_state: if st.session_state["edit_input_data"]: From b00421d3a89dedb79209f19148e3c97b0ae115e7 Mon Sep 17 00:00:00 2001 From: Markus Haller Date: Wed, 8 Nov 2023 17:16:34 +0100 Subject: [PATCH 3/4] use ``st.column_config`` to improve number formatting in tables --- app/ptxboa_functions.py | 52 ++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/app/ptxboa_functions.py b/app/ptxboa_functions.py index 0ad3b2ec..a042af1e 100644 --- a/app/ptxboa_functions.py +++ b/app/ptxboa_functions.py @@ -464,7 +464,8 @@ def content_market_scanning( # show data in tabular form: st.markdown("**Data:**") - st.dataframe(df_plot.style.format(precision=2), use_container_width=True) + column_config = config_number_columns(df_plot, format="%.1f") + st.dataframe(df_plot, use_container_width=True, column_config=column_config) def remove_subregions(api: PtxboaAPI, df: pd.DataFrame, settings: dict): @@ -554,7 +555,11 @@ def content_costs_by_region( create_bar_chart_costs(df_res) st.write("**Data:**") - st.dataframe(df_res.style.format(precision=2), use_container_width=True) + + column_config = config_number_columns( + df_res, format=f"%.1f {settings['output_unit']}" + ) + st.dataframe(df_res, use_container_width=True, column_config=column_config) def content_deep_dive_countries( @@ -622,6 +627,7 @@ def content_deep_dive_countries( "Wind-PV-Hybrid", ] x = "process_code" + column_config = {"format": "%.0f h/a", "min_value": 0, "max_value": 8760} if data_selection == "total costs": df = res_costs.copy() @@ -640,6 +646,7 @@ def content_deep_dive_countries( source_region_code=region_list, parameter_code=parameter_code, process_code=process_code, + column_config=column_config, ) with c1: # create plot: @@ -701,9 +708,8 @@ def content_input_data(api: PtxboaAPI, settings: dict) -> None: "Wind-PV-Hybrid", ] x = "process_code" - column_config = st.column_config.NumberColumn( - format="%.0f USD/kW", - ) + column_config = {"format": "%.0f USD/kW", "min_value": 0} + if data_selection == "full load hours": parameter_code = ["full load hours"] process_code = [ @@ -713,16 +719,13 @@ def content_input_data(api: PtxboaAPI, settings: dict) -> None: "Wind-PV-Hybrid", ] x = "process_code" - column_config = st.column_config.NumberColumn( - format="%.0f h/a", - ) + column_config = {"format": "%.0f h/a", "min_value": 0, "max_value": 8760} + if data_selection == "interest rate": parameter_code = ["interest rate"] process_code = [""] x = "parameter_code" - column_config = st.column_config.NumberColumn( - format="%.3f", - ) + column_config = {"format": "%.3f", "min_value": 0, "max_value": 1} c1, c2 = st.columns(2, gap="medium") with c2: @@ -768,7 +771,7 @@ def display_and_edit_data_table( index: str = "source_region_code", columns: str = "process_code", values: str = "value", - column_config=None, + column_config: dict = None, ) -> pd.DataFrame: """Display selected input data as 2D table, which can also be edited.""" ind1 = input_data["source_region_code"].isin(source_region_code) @@ -786,18 +789,14 @@ def display_and_edit_data_table( key = None # configure columns for display: - column_config_all = {} - for c in df_tab.columns: - if column_config is not None: - column_config_all[c] = column_config - else: - column_config_all[c] = st.column_config.NumberColumn( - format="%.2f", - ) + if column_config is None: + column_config_all = None + else: + column_config_all = config_number_columns(df_tab, **column_config) # display data: st.data_editor( - df_tab.style.format(precision=2), + df_tab, use_container_width=True, key=key, num_rows="fixed", @@ -1147,3 +1146,14 @@ def content_disclaimer(): ) st.image("static/disclaimer.png") st.image("static/disclaimer_2.png") + + +def config_number_columns(df: pd.DataFrame, **kwargs) -> {}: + """Create number column config info for st.dataframe() or st.data_editor.""" + column_config_all = {} + for c in df.columns: + column_config_all[c] = st.column_config.NumberColumn( + **kwargs, + ) + + return column_config_all From 998e5013397693cf252e577e5bb0ee66741542d1 Mon Sep 17 00:00:00 2001 From: Markus Haller Date: Fri, 10 Nov 2023 10:28:49 +0100 Subject: [PATCH 4/4] fix float number format in user changes table --- app/ptxboa_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ptxboa_functions.py b/app/ptxboa_functions.py index a042af1e..f315cc6e 100644 --- a/app/ptxboa_functions.py +++ b/app/ptxboa_functions.py @@ -760,7 +760,7 @@ def display_user_changes(): """Display input data changes made by user.""" if "user_changes_df" in st.session_state.keys(): st.write("**Input data has been modified:**") - st.write(st.session_state["user_changes_df"]) + st.dataframe(st.session_state["user_changes_df"].style.format(precision=3)) def display_and_edit_data_table(