diff --git a/ccsr/config-defaults.yaml b/ccsr/config-defaults.yaml index a25e2b7a..4ae1d58b 100644 --- a/ccsr/config-defaults.yaml +++ b/ccsr/config-defaults.yaml @@ -30,4 +30,10 @@ maprooms: variable: Precipitation var: precip issue_format: "%b %Y" + - title: terc_fcst_temp + core_path: terc_fcst_temp + forecast_path: /Data/data21/iri/FD/NMME_Seasonal_Forecast/Temperature_ELR + variable: Temperature + var: tref + issue_format: "%b %Y" \ No newline at end of file diff --git a/ccsr/config-iri.yaml b/ccsr/config-iri.yaml index 73765c3e..3f668cfc 100644 --- a/ccsr/config-iri.yaml +++ b/ccsr/config-iri.yaml @@ -43,3 +43,9 @@ maprooms: variable: Precipitation var: precip issue_format: "%b %Y" + - title: terc_fcst_temp + core_path: terc_fcst_temp + forecast_path: /Data/data21/iri/FD/NMME_Seasonal_Forecast/Temperature_ELR + variable: Temperature + var: tref + issue_format: "%b %Y" diff --git a/ccsr/terc_fcst/layout.py b/ccsr/terc_fcst/layout.py index 5b7a6369..bab6a9db 100644 --- a/ccsr/terc_fcst/layout.py +++ b/ccsr/terc_fcst/layout.py @@ -8,7 +8,7 @@ IRI_GRAY = "rgb(113,112,116)" LIGHT_GRAY = "#eeeeee" -def app_layout(): +def app_layout(config): return lou.app_1( @@ -19,18 +19,18 @@ def app_layout(): ), lou.description( - "Precipitation Terciles Seasonal Forecast", - """ - The seasonal forecast for above-, below- and near-normal precipitation + f"{config['variable']} Terciles Seasonal Forecast", + f""" + The seasonal forecast for above-, below- and near-normal {config['variable']} from the IRI. """, html.P( - """ - The default map shows globally the seasonal precipitation forecast - tercile probability. The historical climatology used is 1982-2010 up - to the forecast issued in August 2021, and is 1991-2020 from the - forecast issued in September 2021. The forecast shown is the latest - forecast made (e.g. Dec 2017) for the next season to come + f""" + The default map shows globally the seasonal {config['variable']} + forecast tercile probability. The historical climatology used is + 1982-2010 up to the forecast issued in August 2021, and is 1991-2020 + from the forecast issued in September 2021. The forecast shown is + the latest forecast made (e.g. Dec 2017) for the next season to come (e.g. Jan-Mar 2018). Four different seasons are forecasted and it is also possible to consult forecasts made previously. The forecasts are directly computed from the extended logistic regression model as diff --git a/ccsr/terc_fcst/maproom.py b/ccsr/terc_fcst/maproom.py index 77d74979..c65f6bb1 100644 --- a/ccsr/terc_fcst/maproom.py +++ b/ccsr/terc_fcst/maproom.py @@ -35,7 +35,7 @@ def register(FLASK, config): ) APP.title = "Tercile Forecast" - APP.layout = layout.app_layout() + APP.layout = layout.app_layout(config) @APP.callback( Output("start_div", "children"), @@ -60,13 +60,18 @@ def initialize(path): options=[ld["value"] for ld in target_dict], labels=[ld["label"] for ld in target_dict], ) + if config["variable"] == "Precipitation": + cs_below = "prcp_terciles_below" + cs_above = "prcp_terciles_above" + else: + cs_below = "temp_terciles_below" + cs_above = "temp_terciles_above" return ( issue_select, lead_select, # while the data is classified and mapped according to classification # colormap, I draw the colorscale from 2 colormaps (for below and above) # corresponding to those classifications and with the probability values - CMAPS["prcp_terciles_below"].to_dash_leaflet(), - CMAPS["prcp_terciles_above"].to_dash_leaflet(), + CMAPS[cs_below].to_dash_leaflet(), CMAPS[cs_above].to_dash_leaflet(), ) + mru.initialize_map(fcst_ds) @@ -141,8 +146,18 @@ def local_plots(marker_pos, start_date, lead_time, targets): lng_units = "˚E" if (fcst_ds['X'] >= 0) else "˚W" lat_units = "˚N" if (fcst_ds['Y'] >= 0) else "˚S" #Get colors from the colormap to assign each bar + if config["variable"] == "Precipitation": + cs_below = "prcp_terciles_below" + cs_above = "prcp_terciles_above" + low_below = "lightyellow" + low_above = "rgb(220, 255, 220)" + else: + cs_below = "temp_terciles_below" + cs_above = "temp_terciles_above" + low_below = "azure" + low_above = "lightpink" if fcst_ds["prob"].isel(cat=0) >= 37.5: - below_color = CMAPS["prcp_terciles_below"].to_rgba_array()[ + below_color = CMAPS[cs_below].to_rgba_array()[ int( 0.5 + 255 @@ -155,9 +170,9 @@ def local_plots(marker_pos, start_date, lead_time, targets): f"rgb({below_color[0]}, {below_color[1]}, {below_color[2]})" ) else: - below_color = "lightyellow" + below_color = low_below if fcst_ds["prob"].isel(cat=2) >= 37.5: - above_color = CMAPS["prcp_terciles_above"].to_rgba_array()[ + above_color = CMAPS[cs_above].to_rgba_array()[ int( 0.5 + 255 @@ -170,7 +185,7 @@ def local_plots(marker_pos, start_date, lead_time, targets): f"rgb({above_color[0]}, {above_color[1]}, {above_color[2]})" ) else: - above_color = "rgb(220, 255, 220)" + above_color = low_above local_graph = px.bar( ( fcst_ds["prob"] @@ -254,7 +269,11 @@ def fcst_tiles(tz, tx, ty, start_date, lead_time): ], [lambda x : x, lambda x : x - 4, 6], ) - dominant_fcst_class.attrs["colormap"] = CMAPS["prcp_terciles"] + if config["variable"] == "Precipitation": + cs_terc = "prcp_terciles" + else: + cs_terc = "temp_terciles" + dominant_fcst_class.attrs["colormap"] = CMAPS[cs_terc] dominant_fcst_class.attrs["scale_min"] = 0 dominant_fcst_class.attrs["scale_max"] = 11 return pingrid.tile( diff --git a/pingrid/impl.py b/pingrid/impl.py index e1c5a8d4..2eddb839 100644 --- a/pingrid/impl.py +++ b/pingrid/impl.py @@ -880,6 +880,51 @@ def produce_shape_tile( [37.5, 42.5, 42.5, 47.5, 47.7, 57.5, 57.5, 67.5, 67.5, 100], ) + +_TEMP_TERCILES_CS = ColorScale( + "temp_terciles", + [ + WHITE, WHITE, + Color(200, 240, 250), Color(200, 240, 250), + Color(177, 202, 250), Color(177, 202, 250), + Color(153, 163, 250), Color(153, 163, 250), + Color(129, 124, 250), Color(129, 124, 250), + Color(85, 85, 200), Color(85, 85, 200), + GRAY, GRAY, + Color(255, 210, 210), Color(255, 210, 210), + Color(242, 170, 170), Color(242, 170, 170), + Color(250, 120, 120), Color(250, 120, 120), + Color(255, 40, 40), Color(255, 40, 40), + Color(150, 19, 19), Color(150, 19, 18), + ], + [0, 0.5, 0.5, 1.5, 1.5, 2.5, 2.5, 3.5, 3.5, 4.5, 4.5, 5.5, + 5.5, 6.5, 6.5, 7.5, 7.5, 8.5, 8.5, 9.5, 9.5, 10.5, 10.5, 11], +) + +_TEMP_TERCILES_BELOW_CS = ColorScale( + "temp_terciles_below", + [ + Color(200, 240, 250), Color(200, 240, 250), + Color(177, 202, 250), Color(177, 202, 250), + Color(153, 163, 250), Color(153, 163, 250), + Color(129, 124, 250), Color(129, 124, 250), + Color(85, 85, 200), Color(85, 85, 200), + ], + [37.5, 42.5, 42.5, 47.5, 47.7, 57.5, 57.5, 67.5, 67.5, 100], +) + +_TEMP_TERCILES_ABOVE_CS = ColorScale( + "temp_terciles_above", + [ + Color(255, 210, 210), Color(255, 210, 210), + Color(242, 170, 170), Color(242, 170, 170), + Color(250, 120, 120), Color(250, 120, 120), + Color(255, 40, 40), Color(255, 40, 40), + Color(150, 19, 19), Color(150, 19, 18), + ], + [37.5, 42.5, 42.5, 47.5, 47.7, 57.5, 57.5, 67.5, 67.5, 100], +) + _RAIN_POE_CS = ColorScale( "rain_poe", [BLACK, BROWN, ORANGE, YELLOW, MOCCASIN, MOCCASIN, LIMEGREEN, TURQUOISE, BLUE, PURPLE], @@ -1034,6 +1079,9 @@ def produce_shape_tile( _STD_ANOMALY_CS, _TEMP_CS, _TEMP_ANOMALY_CS, + _TEMP_TERCILES_CS, + _TEMP_TERCILES_ABOVE_CS, + _TEMP_TERCILES_BELOW_CS, _VULN_CS, ]}