From 94d4cecb94d2bb0ee192f99d659f5461c53e6d45 Mon Sep 17 00:00:00 2001 From: williamstravis Date: Tue, 16 Jul 2024 12:39:24 -0600 Subject: [PATCH] More column name change fixes --- configs/oop_geotherm_fy24.json | 4 ++ reView/components/callbacks.py | 11 ++-- reView/components/map.py | 15 +++--- reView/index.py | 1 + reView/pages/rev/controller/callbacks.py | 51 ++++++++----------- .../pages/rev/controller/element_builders.py | 25 +++++++-- 6 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 configs/oop_geotherm_fy24.json diff --git a/configs/oop_geotherm_fy24.json b/configs/oop_geotherm_fy24.json new file mode 100644 index 0000000..48d336b --- /dev/null +++ b/configs/oop_geotherm_fy24.json @@ -0,0 +1,4 @@ +{ + "project_name": "Office of Policy - Geothermal- FY24", + "directory": "~/review_datasets/oop_geothermal_fy24" +} diff --git a/reView/components/callbacks.py b/reView/components/callbacks.py index 6f69d0b..4007c50 100644 --- a/reView/components/callbacks.py +++ b/reView/components/callbacks.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- """Common reView callbacks. """ -from dash.dependencies import Input, Output +from dash.dependencies import Input, Output, State from reView.app import app -from reView.layout.styles import RC_STYLES from reView.components.logic import tab_styles, format_capacity_title +from reView.layout.styles import RC_STYLES +from reView.pages.rev.controller.element_builders import find_capacity from reView.utils import calls @@ -115,10 +116,12 @@ def capacity_print(id_prefix): Output(f"{id_prefix}_site_print", "children"), Input(f"{id_prefix}_mapcap", "children"), Input(f"{id_prefix}_map", "selectedData"), + State("project", "value") ) @calls.log - def _capacity_print(map_capacity, map_selection): + def _capacity_print(map_capacity, map_selection, project): """Calculate total remaining capacity.""" - return format_capacity_title(map_capacity, map_selection) + capcol = find_capacity(project) + return format_capacity_title(map_capacity, map_selection, capcol) return _capacity_print diff --git a/reView/components/map.py b/reView/components/map.py index 2e56b21..437442b 100644 --- a/reView/components/map.py +++ b/reView/components/map.py @@ -23,6 +23,7 @@ convert_to_title, strip_rev_filename_endings ) +from reView.pages.rev.controller.element_builders import find_capacity from reView.pages.rev.model import point_filter logger = logging.getLogger(__name__) @@ -90,6 +91,7 @@ def __init__(self, df, signal_dict, color_var, project, map_selection=None, self.chart_selection = chart_selection self.delimiter = delimiter self.x_var = x_var + self.capcol = find_capacity(project) @property def scenario(self): @@ -194,7 +196,7 @@ def _add_extras_to_title(self, title, units): # we can make this more general by # allowing user input about this in config - if "capacity" in self.no_diff_suffix and units != "percent": + if self.capcol in self.no_diff_suffix and units != "percent": extra = self._add_total_info("MW", extra) title = self.delimiter.join([title, extra]) @@ -233,11 +235,11 @@ def _apply_aggregation(self, units, agg_type): except KeyError: weights = df["solar_area_sq_km"] elif "area_sq_km" not in df: # Quick fix change for bespoke hybrids - weights = df["capacity"] + weights = df[self.capcol] else: weights = df["area_sq_km"] - skippers = ["capacity", "area_sq_km"] # Don't use weights for these + skippers = [self.capcol, "area_sq_km"] # Don't use weights for these if (agg_type == "mean" and self.color_var not in skippers): aggregation = np.average( @@ -301,6 +303,7 @@ def __init__( df, color_var, project, color_range[0], color_range[1] ) self.demand_data = demand_data + self.capcol = find_capacity(project) if project: self.config = Config(project) @@ -361,7 +364,7 @@ def figure(self, point_size, reverse_color=False): lon="longitude", lat="latitude", color_discrete_map=colormap, - custom_data=["sc_point_gid", "capacity"], + custom_data=["sc_point_gid", self.capcol], hover_name="text", ) else: @@ -371,7 +374,7 @@ def figure(self, point_size, reverse_color=False): lon="longitude", lat="latitude", color_discrete_sequence=px.colors.qualitative.Safe, - custom_data=["sc_point_gid", "capacity"], + custom_data=["sc_point_gid", self.capcol], hover_name="text", ) figure.update_traces(marker=self.marker(point_size, reverse_color)) @@ -381,7 +384,7 @@ def figure(self, point_size, reverse_color=False): data_frame=self.df, lon="longitude", lat="latitude", - custom_data=["sc_point_gid", "capacity"], + custom_data=["sc_point_gid", self.capcol], hover_name="text", ) diff --git a/reView/index.py b/reView/index.py index 87a44ea..606f824 100644 --- a/reView/index.py +++ b/reView/index.py @@ -24,6 +24,7 @@ def main(): host=APP_HOST, port=APP_PORT, debug=False, + dev_tools_hot_reload=False ) diff --git a/reView/pages/rev/controller/callbacks.py b/reView/pages/rev/controller/callbacks.py index 7933964..781f84c 100644 --- a/reView/pages/rev/controller/callbacks.py +++ b/reView/pages/rev/controller/callbacks.py @@ -38,7 +38,7 @@ COLOR_Q_OPTIONS, ) from reView.layout.styles import TABLET_STYLE -from reView.pages.rev.controller.element_builders import Plots +from reView.pages.rev.controller.element_builders import Plots, find_capacity from reView.pages.rev.controller.selection import ( choose_scenario, get_variable_options, @@ -169,7 +169,8 @@ def build_specs(scenario, project): def build_spec_split(path, project): """Calculate the percentage of each scenario present.""" - df = cache_table(project, y_var="capacity", x_var="mean_lcoe", path=path) + cap_field = find_capacity(project) + df = cache_table(project, y_var=cap_field, x_var="mean_lcoe", path=path) # Also find mean lcoe field (new field = lcoe_site_usd_per_mwh) scenarios, counts = np.unique(df["scenario"], return_counts=True) total = df.shape[0] percentages = [counts[i] / total for i in range(len(counts))] @@ -321,17 +322,6 @@ def files_to_dropdown(files): return scenario_options -def find_capacity(project): - """Find a useable capacity string from a list of column names.""" - config = Config(project) - file = config.files[next(iter(config.files))] - columns = read_file(file, nrows=0).columns - capcols = [col for col in columns if "capacity" in col] - if len(capcols) == 0: - raise KeyError("No capacity column found!") - return capcols[0] - - @calls.log def options_chart_type(project, y_var=None): """Add characterization plot option, if necessary.""" @@ -977,7 +967,7 @@ def figure_chart( # Collect minimum needed inputs x_var = signal_dict["x"] if x_var == "None": - x_var = "capacity" + x_var = find_capacity(project) y_var = signal_dict["y"] project = signal_dict["project"] @@ -986,21 +976,21 @@ def figure_chart( # Return empty alert if all(df.empty for df in dfs.values()): - figure = go.Figure() - figure.update_layout( - xaxis={"visible": False}, - yaxis={"visible": False}, - annotations=[ - { - "text": "No matching data found", - "xref": "paper", - "yref": "paper", - "showarrow": False, - "font": {"size": 28}, - } - ], - ) - return figure + raise PreventUpdate # Error Popup? + # figure = go.Figure() + # figure.update_layout( + # xaxis={"visible": False}, + # yaxis={"visible": False}, + # annotations=[ + # { + # "text": "No matching data found", + # "xref": "paper", + # "yref": "paper", + # "showarrow": False, + # "font": {"size": 28}, + # } + # ], + # ) # Turn the map selection object into indices if map_selection: @@ -1158,7 +1148,8 @@ def figure_map( point_size=point_size, reverse_color=reverse_color_clicks % 2 == 1, ) - mapcap = df[["sc_point_gid", "capacity"]].to_dict() + capcol = find_capacity(project) + mapcap = df[["sc_point_gid", capcol]].to_dict() # Package returns mapcap = json.dumps(mapcap) diff --git a/reView/pages/rev/controller/element_builders.py b/reView/pages/rev/controller/element_builders.py index d8e0ee4..2a66660 100644 --- a/reView/pages/rev/controller/element_builders.py +++ b/reView/pages/rev/controller/element_builders.py @@ -22,13 +22,26 @@ from reView.utils.classes import DiffUnitOptions from reView.utils.config import Config from reView.utils.constants import DEFAULT_POINT_SIZE, DEFAULT_LAYOUT -from reView.utils.functions import convert_to_title +from reView.utils.functions import convert_to_title, read_file CHART_LAYOUT = copy.deepcopy(DEFAULT_LAYOUT) CHART_LAYOUT.update({"legend_title_font_color": "black"}) +def find_capacity(project): + """Find a useable capacity string from a list of column names.""" + config = Config(project) + file = config.files[next(iter(config.files))] + columns = read_file(file, nrows=0).columns + capcols = [col for col in columns if "capacity" in col] + capcols = [col for col in capcols if "factor" not in col] + # capcols.sort() # Need to figure out how to handle ac vs dc + if len(capcols) == 0: + raise KeyError("No capacity column found!") + return capcols[0] + + def _fix_doubles(df): """Check and/or fix columns names when they match.""" if not isinstance(df, pd.core.frame.Series): @@ -71,7 +84,9 @@ def __init__( self.point_size = point_size self.user_scale = user_scale self.alpha = alpha + self.project = project self.config = Config(project) + self.capcol = find_capacity(project) def __repr__(self): """Print representation string.""" @@ -110,7 +125,7 @@ def binned(self, x_var, y_var, bins=100): main_df, x="xbin", y="yagg", # Plot all y's so we can share selections with map - custom_data=["sc_point_gid", self.capacity_col(main_df)], + custom_data=["sc_point_gid", self.capcol], labels={x_var: xtitle, y_var: ytitle}, color=self.GROUP, color_discrete_sequence=px.colors.qualitative.Safe, @@ -178,7 +193,7 @@ def fix_key(key): main_df, x=self.GROUP, y=y_var, - custom_data=["sc_point_gid", "capacity"], + custom_data=["sc_point_gid", self.capcol], labels={y_var: y_title}, color=self.GROUP, color_discrete_sequence=px.colors.qualitative.Safe, @@ -288,7 +303,7 @@ def cumulative_sum(self, x_var, y_var): main_df, x="cumsum", y=y_var, - custom_data=["sc_point_gid", "capacity"], + custom_data=["sc_point_gid", self.capcol], labels={ "cumsum": f"Cumulative {x_title}", y_var: y_title, @@ -385,7 +400,7 @@ def scatter(self, x_var, y_var): x=x_var, y=y_var, opacity=self.alpha, - custom_data=["sc_point_gid", "capacity"], + custom_data=["sc_point_gid", self.capcol], labels={x_var: x_title, y_var: y_title}, color=self.GROUP, color_discrete_sequence=px.colors.qualitative.Safe,