From 7174f20444626efcdb9c743ba0f709dddf9b02a2 Mon Sep 17 00:00:00 2001 From: Le Roux Erwan <erwan.le-roux@irstea.fr> Date: Thu, 18 Feb 2021 17:04:19 +0100 Subject: [PATCH] [projections] modify year 2019 in OneFoldFit !!! improve visualizer_for_projection_ensemble.py --- .../visualization/study_visualizer.py | 1 + .../altitudes_fit/main_altitudes_studies.py | 2 +- ...es_visualizer_for_non_stationary_models.py | 29 +++---- .../one_fold_analysis/one_fold_fit.py | 21 ++--- .../plots/plot_histogram_altitude_studies.py | 9 ++- .../ensemble_fit/abstract_ensemble_fit.py | 3 - .../ensemble_fit/independent_ensemble_fit.py | 14 +--- ...ation_temporal_for_projections_ensemble.py | 52 +++++++------ .../utils_projected_visualizer.py | 38 --------- .../visualizer_for_projection_ensemble.py | 77 +++++++++++++------ 10 files changed, 119 insertions(+), 127 deletions(-) delete mode 100644 projects/projected_snowfall/elevation_temporal_model_for_projections/utils_projected_visualizer.py diff --git a/extreme_data/meteo_france_data/scm_models_data/visualization/study_visualizer.py b/extreme_data/meteo_france_data/scm_models_data/visualization/study_visualizer.py index 71b0e606..50a12b74 100644 --- a/extreme_data/meteo_france_data/scm_models_data/visualization/study_visualizer.py +++ b/extreme_data/meteo_france_data/scm_models_data/visualization/study_visualizer.py @@ -545,6 +545,7 @@ class StudyVisualizer(VisualizationParameters): dpi=None, folder_for_variable=True): if isinstance(self.study, AbstractAdamontStudy): prefix = gcm_rcm_couple_to_str(self.study.gcm_rcm_couple) + prefix = prefix.replace('/', '-') self.plot_name = prefix + ' ' + self.plot_name assert self.plot_name is not None diff --git a/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py b/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py index 12624a00..cf17d088 100644 --- a/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py +++ b/projects/altitude_spatial_model/altitudes_fit/main_altitudes_studies.py @@ -86,7 +86,7 @@ def plot_visualizers(massif_names, visualizer_list): # plot_shoe_plot_ratio_interval_size_against_altitude(massif_names, visualizer_list) for relative in [True, False]: plot_shoe_plot_changes_against_altitude(massif_names, visualizer_list, relative=relative) - # plot_coherence_curves(massif_names, visualizer_list) + plot_coherence_curves(massif_names, visualizer_list) # plot_coherence_curves(['Vanoise'], visualizer_list) pass diff --git a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitudes_studies_visualizer_for_non_stationary_models.py b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitudes_studies_visualizer_for_non_stationary_models.py index 28861c40..e3a4c4f2 100644 --- a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitudes_studies_visualizer_for_non_stationary_models.py +++ b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/altitudes_studies_visualizer_for_non_stationary_models.py @@ -141,7 +141,8 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): return self._method_name_and_order_to_massif_name_to_value[c] def ratio_groups(self): - return [self.ratio_uncertainty_interval_size(altitude, 2019) for altitude in self.studies.altitudes] + return [self.ratio_uncertainty_interval_size(altitude, OneFoldFit.last_year) for altitude in + self.studies.altitudes] def ratio_uncertainty_interval_size(self, altitude, year): study = self.studies.altitude_to_study[altitude] @@ -164,14 +165,13 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): massif_name_to_value = self.method_name_and_order_to_d(method_name, order) # Plot settings moment = ' '.join(method_name.split('_')) - str_for_last_year = ' in 2019' + str_for_last_year = ' in {}'.format(OneFoldFit.last_year) moment = moment.replace('moment', '{}{}'.format(OneFoldFit.get_moment_str(order=order), str_for_last_year)) plot_name = '{}{} '.format(OneFoldFit.folder_for_plots, moment) - if 'change' in method_name: plot_name = plot_name.replace(str_for_last_year, '') - plot_name += ' between {} and {}'.format(2019 - OneFoldFit.nb_years, 2019) + plot_name += ' between {} and {}'.format(OneFoldFit.last_year - OneFoldFit.nb_years, OneFoldFit.last_year) if 'relative' not in method_name: # Put the relative score as text on the plot for the change. massif_name_to_text = {m: ('+' if v > 0 else '') + str(int(v)) + '\%' for m, v in @@ -218,11 +218,10 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): fontsize_label=fontsize_label, ) - @property def add_colorbar(self): - # return isinstance(self.altitude_group, (VeyHighAltitudeGroup)) - return isinstance(self.altitude_group, (VeyHighAltitudeGroup, MidAltitudeGroup)) + return True + # return isinstance(self.altitude_group, (VeyHighAltitudeGroup, MidAltitudeGroup)) def plot_against_years(self, method_name, order): ax = plt.gca() @@ -238,7 +237,8 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): # Plot settings ax.legend(prop={'size': 7}, ncol=3) moment = ' '.join(method_name.split('_')) - moment = moment.replace('moment', '{} in 2019'.format(OneFoldFit.get_moment_str(order=order))) + moment = moment.replace('moment', + '{} in {}'.format(OneFoldFit.get_moment_str(order=order), OneFoldFit.last_year)) plot_name = '{}Model {} annual maxima of {}'.format(OneFoldFit.folder_for_plots, moment, SCM_STUDY_CLASS_TO_ABBREVIATION[self.studies.study_class]) ax.set_ylabel('{} ({})'.format(plot_name, self.study.variable_unit), fontsize=15) @@ -286,7 +286,7 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): if AbstractCoordinates.COORDINATE_X in coordinate_name: massif_name_to_best_coef[massif_name] *= np.power(1000, degree) if AbstractCoordinates.COORDINATE_T in coordinate_name: - massif_name_to_best_coef[massif_name] *= np.power(2019, degree) + massif_name_to_best_coef[massif_name] *= np.power(OneFoldFit.last_year, degree) self.plot_best_coef_map(coef_name.replace('_', ''), massif_name_to_best_coef) def plot_best_coef_map(self, coef_name, massif_name_to_best_coef): @@ -306,7 +306,7 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): def plot_shape_map(self): - label = 'Shape parameter in 2019 (no unit)' + label = 'Shape parameter in {} (no unit)'.format(OneFoldFit.last_year) max_abs_change = self._max_abs_for_shape + 0.05 self.plot_map(massif_name_to_value=self.massif_name_to_shape, label=label, @@ -437,7 +437,7 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): self.studies.show_or_save_to_file(plot_name=plot_name, show=self.show) plt.close() - def all_trends(self, massif_names): + def all_trends(self, massif_names, with_significance=True): """return percents which contain decrease, significant decrease, increase, significant increase percentages""" valid_massif_names = self.get_valid_names(massif_names) @@ -451,8 +451,8 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): # Compute nbs idx = 0 if one_fold.change_in_return_level_for_reference_altitude < 0 else 2 nbs[idx] += 1 - if one_fold.is_significant: - nbs[idx + 1] += 1 + if with_significance and one_fold.is_significant: + nbs[idx + 1] += 1 percents = 100 * nbs / nb_valid_massif_names return [nb_valid_massif_names] + list(percents) @@ -515,7 +515,8 @@ class AltitudesStudiesVisualizerForNonStationaryModels(StudyVisualizer): for altitude in self.studies.altitudes: coordinate_for_filter = (altitude, None) - unconstrained_empirical_quantiles = one_fold_fit.best_estimator.sorted_empirical_standard_gumbel_quantiles(coordinate_for_filter=coordinate_for_filter) + unconstrained_empirical_quantiles = one_fold_fit.best_estimator.sorted_empirical_standard_gumbel_quantiles( + coordinate_for_filter=coordinate_for_filter) n = len(unconstrained_empirical_quantiles) if n > 0: assert n == 61 diff --git a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/one_fold_fit.py b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/one_fold_fit.py index 162e5559..45c65722 100644 --- a/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/one_fold_fit.py +++ b/projects/altitude_spatial_model/altitudes_fit/one_fold_analysis/one_fold_fit.py @@ -45,6 +45,7 @@ class OneFoldFit(object): return_period = 100 quantile_level = 1 - (1 / return_period) nb_years = 60 + last_year = 2019 def __init__(self, massif_name: str, dataset: AbstractDataset, models_classes, fit_method=MarginFitMethod.extremes_fevd_mle, @@ -107,8 +108,8 @@ class OneFoldFit(object): gev_params = self.best_function_from_fit.get_params(coordinate, is_transformed=False) return gev_params - def moment(self, altitudes, year=2019, order=1): - return [self.get_moment(altitude, year, order) for altitude in altitudes] + def moment(self, altitudes, order=1): + return [self.get_moment(altitude, self.last_year, order) for altitude in altitudes] @property def change_in_return_level_for_reference_altitude(self) -> float: @@ -118,20 +119,20 @@ class OneFoldFit(object): def relative_change_in_return_level_for_reference_altitude(self) -> float: return self.relative_changes_of_moment(altitudes=[self.altitude_plot], order=None)[0] - def changes_of_moment(self, altitudes, year=2019, nb_years=nb_years, order=1): + def changes_of_moment(self, altitudes, nb_years=nb_years, order=1): changes = [] for altitude in altitudes: - mean_after = self.get_moment(altitude, year, order) - mean_before = self.get_moment(altitude, year - nb_years, order) + mean_after = self.get_moment(altitude, self.last_year, order) + mean_before = self.get_moment(altitude, self.last_year - nb_years, order) change = mean_after - mean_before changes.append(change) return changes - def relative_changes_of_moment(self, altitudes, year=2019, nb_years=nb_years, order=1): + def relative_changes_of_moment(self, altitudes, nb_years=nb_years, order=1): relative_changes = [] for altitude in altitudes: - mean_after = self.get_moment(altitude, year, order) - mean_before = self.get_moment(altitude, year - nb_years, order) + mean_after = self.get_moment(altitude, self.last_year, order) + mean_before = self.get_moment(altitude, self.last_year - nb_years, order) relative_change = 100 * (mean_after - mean_before) / mean_before relative_changes.append(relative_change) return relative_changes @@ -204,7 +205,7 @@ class OneFoldFit(object): @property def best_shape(self): - return self.get_gev_params(altitude=self.altitude_plot, year=2019).shape + return self.get_gev_params(altitude=self.altitude_plot, year=self.last_year).shape @property def altitude_plot(self): @@ -317,7 +318,7 @@ class OneFoldFit(object): def sign_of_change(self, function_from_fit): return_levels = [] - for year in [2019 - self.nb_years, 2019]: + for year in [self.last_year - self.nb_years, self.last_year]: coordinate = np.array([self.altitude_plot, year]) return_level = function_from_fit.get_params( coordinate=coordinate, diff --git a/projects/altitude_spatial_model/altitudes_fit/plots/plot_histogram_altitude_studies.py b/projects/altitude_spatial_model/altitudes_fit/plots/plot_histogram_altitude_studies.py index 9a818a6d..ca2a3b01 100644 --- a/projects/altitude_spatial_model/altitudes_fit/plots/plot_histogram_altitude_studies.py +++ b/projects/altitude_spatial_model/altitudes_fit/plots/plot_histogram_altitude_studies.py @@ -81,10 +81,10 @@ def plot_histogram_all_models_against_altitudes(massif_names, visualizer_list: L def plot_histogram_all_trends_against_altitudes(massif_names, visualizer_list: List[ - AltitudesStudiesVisualizerForNonStationaryModels]): + AltitudesStudiesVisualizerForNonStationaryModels], with_significance=True): visualizer = visualizer_list[0] - all_trends = [v.all_trends(massif_names) for v in visualizer_list] + all_trends = [v.all_trends(massif_names, with_significance=with_significance) for v in visualizer_list] nb_massifs, *all_l = zip(*all_trends) plt.close() @@ -106,8 +106,9 @@ def plot_histogram_all_trends_against_altitudes(massif_names, visualizer_list: L shift = 0.6 * width is_a_decrease_plot = colors.index(color) in [0, 1] x_shifted = x - shift if is_a_decrease_plot else x + shift - ax.bar(x_shifted, l, width=width, color=color, edgecolor=color, label=label, - linewidth=linewidth, align='center') + if with_significance or (not label.startswith("S")): + ax.bar(x_shifted, l, width=width, color=color, edgecolor=color, label=label, + linewidth=linewidth, align='center') ax.legend(loc='upper left', prop={'size': size}) ax.set_ylabel('Percentage of massifs (\%) ', fontsize=legend_fontsize) ax.set_xlabel('Elevation range', fontsize=legend_fontsize) diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/abstract_ensemble_fit.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/abstract_ensemble_fit.py index b3783021..6a1d7b01 100644 --- a/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/abstract_ensemble_fit.py +++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/abstract_ensemble_fit.py @@ -22,6 +22,3 @@ class AbstractEnsembleFit(object): self.only_models_that_pass_goodness_of_fit_test = only_models_that_pass_goodness_of_fit_test self.confidence_interval_based_on_delta_method = confidence_interval_based_on_delta_method - - def plot(self): - raise NotImplementedError \ No newline at end of file diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/independent_ensemble_fit.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/independent_ensemble_fit.py index 9de456cc..3e15ae0d 100644 --- a/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/independent_ensemble_fit.py +++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/ensemble_fit/independent_ensemble_fit.py @@ -20,6 +20,9 @@ class IndependentEnsembleFit(AbstractEnsembleFit): super().__init__(massif_names, gcm_rcm_couple_to_altitude_studies, models_classes, fit_method, temporal_covariate_for_fit, only_models_that_pass_goodness_of_fit_test, confidence_interval_based_on_delta_method) + # Set appropriate setting + OneFoldFit.last_year = 2100 + OneFoldFit.nb_years = 95 # Load a classical visualizer self.gcm_rcm_couple_to_visualizer = {} for gcm_rcm_couple, studies in gcm_rcm_couple_to_altitude_studies.items(): @@ -35,14 +38,3 @@ class IndependentEnsembleFit(AbstractEnsembleFit): visualizer_list = list(self.gcm_rcm_couple_to_visualizer.values()) compute_and_assign_max_abs(visualizer_list) - def plot(self): - for v in self.gcm_rcm_couple_to_visualizer.values(): - self.plot_one_visualizer(v) - - @staticmethod - def plot_one_visualizer(visualizer): - # visualizer.studies.plot_maxima_time_series(['Vanoise']) - visualizer.plot_shape_map() - visualizer.plot_moments() - # visualizer.plot_qqplots() - diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/main_elevation_temporal_for_projections_ensemble.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/main_elevation_temporal_for_projections_ensemble.py index 33baed2b..88dede3a 100644 --- a/projects/projected_snowfall/elevation_temporal_model_for_projections/main_elevation_temporal_for_projections_ensemble.py +++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/main_elevation_temporal_for_projections_ensemble.py @@ -4,21 +4,21 @@ from typing import List import matplotlib as mpl - mpl.rcParams['text.usetex'] = True mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}'] +from extreme_fit.model.margin_model.polynomial_margin_model.utils import \ + ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS +from projects.projected_snowfall.elevation_temporal_model_for_projections.visualizer_for_projection_ensemble import \ + MetaVisualizerForProjectionEnsemble import matplotlib from extreme_fit.model.utils import set_seed_for_test from extreme_data.meteo_france_data.adamont_data.adamont.adamont_snowfall import AdamontSnowfall -from extreme_data.meteo_france_data.adamont_data.adamont_scenario import AdamontScenario, get_gcm_rcm_couples +from extreme_data.meteo_france_data.adamont_data.adamont_scenario import AdamontScenario, get_gcm_rcm_couples, \ + rcp_scenarios from projects.projected_snowfall.elevation_temporal_model_for_projections.ensemble_fit.independent_ensemble_fit import \ IndependentEnsembleFit -from projects.projected_snowfall.elevation_temporal_model_for_projections.utils_projected_visualizer import \ - load_projected_visualizer_list -from projects.projected_snowfall.elevation_temporal_model_for_projections.visualizer_for_projection_ensemble import \ - VisualizerForProjectionEnsemble from spatio_temporal_dataset.coordinates.temporal_coordinates.abstract_temporal_covariate_for_fit import \ AnomalyTemperatureTemporalCovariate @@ -30,8 +30,6 @@ from projects.altitude_spatial_model.altitudes_fit.plots.plot_histogram_altitude from extreme_fit.model.result_from_model_fit.result_from_extremes.abstract_extract_eurocode_return_level import \ AbstractExtractEurocodeReturnLevel - - from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitude_group import altitudes_for_groups from extreme_data.meteo_france_data.scm_models_data.utils import Season @@ -40,7 +38,7 @@ from extreme_data.meteo_france_data.scm_models_data.utils import Season def main(): study_classes = [AdamontSnowfall][:1] scenario = AdamontScenario.rcp85 - gcm_rcm_couples = get_gcm_rcm_couples(scenario)[:2] + gcm_rcm_couples = get_gcm_rcm_couples(scenario) ensemble_fit_class = [IndependentEnsembleFit] temporal_covariate_for_fit = [None, AnomalyTemperatureTemporalCovariate][0] set_seed_for_test() @@ -49,42 +47,48 @@ def main(): fast = True if fast is None: massif_names = None + gcm_rcm_couples = gcm_rcm_couples[:2] AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10 altitudes_list = altitudes_for_groups[2:3] elif fast: AbstractExtractEurocodeReturnLevel.NB_BOOTSTRAP = 10 - massif_names = ['Vanoise'][:] + massif_names = ['Vanoise', 'Haute-Maurienne', 'Vercors'][:] + gcm_rcm_couples = gcm_rcm_couples[:2] altitudes_list = altitudes_for_groups[1:2] else: massif_names = None altitudes_list = altitudes_for_groups[:] start = time.time() - main_loop(gcm_rcm_couples, altitudes_list, massif_names, study_classes, ensemble_fit_class, scenario, temporal_covariate_for_fit) + main_loop(gcm_rcm_couples, altitudes_list, massif_names, study_classes, ensemble_fit_class, scenario, + temporal_covariate_for_fit) end = time.time() duration = str(datetime.timedelta(seconds=end - start)) print('Total duration', duration) -def main_loop(gcm_rcm_couples, altitudes_list, massif_names, study_classes, ensemble_fit_classes, scenario, temporal_covariate_for_fit): +def main_loop(gcm_rcm_couples, altitudes_list, massif_names, study_classes, ensemble_fit_classes, scenario, + temporal_covariate_for_fit): assert isinstance(altitudes_list, List) assert isinstance(altitudes_list[0], List) for study_class in study_classes: print('Inner loop', study_class) - visualizer_list = load_projected_visualizer_list(gcm_rcm_couples=gcm_rcm_couples, ensemble_fit_classes=ensemble_fit_classes, - season=Season.annual, study_class=study_class, - altitudes_list=altitudes_list, massif_names=massif_names, - scenario=scenario, - temporal_covariate_for_fit=temporal_covariate_for_fit) - for v in visualizer_list: - v.plot() - - del visualizer_list + model_classes = ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS + assert scenario in rcp_scenarios + + visualizer = MetaVisualizerForProjectionEnsemble( + altitudes_list, gcm_rcm_couples, study_class, Season.annual, scenario, + model_classes=model_classes, + ensemble_fit_classes=ensemble_fit_classes, + massif_names=massif_names, + temporal_covariate_for_fit=temporal_covariate_for_fit, + confidence_interval_based_on_delta_method=False, + display_only_model_that_pass_gof_test=False + ) + visualizer.plot() + del visualizer time.sleep(2) - - - if __name__ == '__main__': main() diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/utils_projected_visualizer.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/utils_projected_visualizer.py deleted file mode 100644 index a7f70c95..00000000 --- a/projects/projected_snowfall/elevation_temporal_model_for_projections/utils_projected_visualizer.py +++ /dev/null @@ -1,38 +0,0 @@ -from extreme_data.meteo_france_data.adamont_data.adamont_scenario import AdamontScenario, rcp_scenarios -from extreme_fit.model.margin_model.polynomial_margin_model.utils import \ - ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS -from projects.altitude_spatial_model.altitudes_fit.altitudes_studies import AltitudesStudies -from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitudes_studies_visualizer_for_non_stationary_models import \ - AltitudesStudiesVisualizerForNonStationaryModels -from projects.projected_snowfall.elevation_temporal_model_for_projections.visualizer_for_projection_ensemble import \ - VisualizerForProjectionEnsemble - - -def load_projected_visualizer_list(gcm_rcm_couples, ensemble_fit_classes, - season, study_class, altitudes_list, massif_names, model_must_pass_the_test=False, - scenario=AdamontScenario.rcp85, - temporal_covariate_for_fit=None, **kwargs_study): - model_classes = ALTITUDINAL_GEV_MODELS_BASED_ON_POINTWISE_ANALYSIS - assert scenario in rcp_scenarios - visualizer_list = [] - # Load all studies - for altitudes in altitudes_list: - gcm_rcm_couple_to_altitude_studies = {} - for gcm_rcm_couple in gcm_rcm_couples: - studies = AltitudesStudies(study_class, altitudes, season=season, - scenario=scenario, gcm_rcm_couple=gcm_rcm_couple, **kwargs_study) - gcm_rcm_couple_to_altitude_studies[gcm_rcm_couple] = studies - visualizer = VisualizerForProjectionEnsemble(gcm_rcm_couple_to_altitude_studies=gcm_rcm_couple_to_altitude_studies, - model_classes=model_classes, - ensemble_fit_classes=ensemble_fit_classes, - massif_names=massif_names, - show=False, - temporal_covariate_for_fit=temporal_covariate_for_fit, - confidence_interval_based_on_delta_method=False, - display_only_model_that_pass_gof_test=model_must_pass_the_test - ) - visualizer_list.append(visualizer) - - return visualizer_list - - diff --git a/projects/projected_snowfall/elevation_temporal_model_for_projections/visualizer_for_projection_ensemble.py b/projects/projected_snowfall/elevation_temporal_model_for_projections/visualizer_for_projection_ensemble.py index 86ffe406..7e9185cd 100644 --- a/projects/projected_snowfall/elevation_temporal_model_for_projections/visualizer_for_projection_ensemble.py +++ b/projects/projected_snowfall/elevation_temporal_model_for_projections/visualizer_for_projection_ensemble.py @@ -27,15 +27,18 @@ from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.altitude_gr get_altitude_group_from_altitudes, HighAltitudeGroup, VeyHighAltitudeGroup, MidAltitudeGroup from projects.altitude_spatial_model.altitudes_fit.one_fold_analysis.one_fold_fit import \ OneFoldFit +from projects.altitude_spatial_model.altitudes_fit.plots.plot_histogram_altitude_studies import \ + plot_histogram_all_trends_against_altitudes, plot_shoe_plot_changes_against_altitude +from projects.projected_snowfall.elevation_temporal_model_for_projections.ensemble_fit.independent_ensemble_fit import \ + IndependentEnsembleFit from spatio_temporal_dataset.coordinates.abstract_coordinates import AbstractCoordinates from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset -class VisualizerForProjectionEnsemble(StudyVisualizer): +class MetaVisualizerForProjectionEnsemble(object): - def __init__(self, gcm_rcm_couple_to_altitude_studies: Dict[str, AltitudesStudies], + def __init__(self, altitudes_list, gcm_rcm_couples, study_class, season, scenario, model_classes: List[AbstractSpatioTemporalPolynomialModel], - show=False, ensemble_fit_classes=None, massif_names=None, fit_method=MarginFitMethod.extremes_fevd_mle, @@ -43,26 +46,56 @@ class VisualizerForProjectionEnsemble(StudyVisualizer): display_only_model_that_pass_gof_test=False, confidence_interval_based_on_delta_method=False ): - studies = list(gcm_rcm_couple_to_altitude_studies.values())[0] - study = studies.study - super().__init__(study, show=show, save_to_file=not show) - # Load one fold fit - self.massif_name_to_massif_altitudes = {} - self.ensemble_class_to_ensemble_fit = {} - for ensemble_fit_class in ensemble_fit_classes: - ensemble_fit = ensemble_fit_class(massif_names, gcm_rcm_couple_to_altitude_studies, model_classes, - fit_method, temporal_covariate_for_fit, - display_only_model_that_pass_gof_test, - confidence_interval_based_on_delta_method) - self.ensemble_class_to_ensemble_fit[ensemble_fit_class] = ensemble_fit + self.gcm_rcm_couples = gcm_rcm_couples + self.massif_names = massif_names + self.ensemble_fit_classes = ensemble_fit_classes - def plot(self): - self.plot_independent() - self.plot_dependent() + # Load all studies + altitude_group_to_gcm_couple_to_studies = {} + for altitudes in altitudes_list: + altitude_group = get_altitude_group_from_altitudes(altitudes) + gcm_rcm_couple_to_studies = {} + for gcm_rcm_couple in gcm_rcm_couples: + studies = AltitudesStudies(study_class, altitudes, season=season, + scenario=scenario, gcm_rcm_couple=gcm_rcm_couple) + gcm_rcm_couple_to_studies[gcm_rcm_couple] = studies + altitude_group_to_gcm_couple_to_studies[altitude_group] = gcm_rcm_couple_to_studies - def plot_dependent(self): - pass + # Load ensemble fit + self.altitude_group_to_ensemble_class_to_ensemble_fit = {} + for altitude_group, gcm_rcm_couple_to_studies in altitude_group_to_gcm_couple_to_studies.items(): + ensemble_class_to_ensemble_fit = {} + for ensemble_fit_class in ensemble_fit_classes: + ensemble_fit = ensemble_fit_class(massif_names, gcm_rcm_couple_to_studies, model_classes, + fit_method, temporal_covariate_for_fit, + display_only_model_that_pass_gof_test, + confidence_interval_based_on_delta_method) + ensemble_class_to_ensemble_fit[ensemble_fit_class] = ensemble_fit + self.altitude_group_to_ensemble_class_to_ensemble_fit[altitude_group] = ensemble_class_to_ensemble_fit + + def plot(self): + if IndependentEnsembleFit in self.ensemble_fit_classes: + self.plot_independent() def plot_independent(self): - for ensemble_fit in self.ensemble_class_to_ensemble_fit.values(): - ensemble_fit.plot() + with_significance = False + # Individual plots + for independent_ensemble_fit in self.ensemble_fits(IndependentEnsembleFit): + for v in independent_ensemble_fit.gcm_rcm_couple_to_visualizer.values(): + v.plot_moments() + # Aggregated at gcm_rcm_level plots + for gcm_rcm_couple in self.gcm_rcm_couples: + visualizer_list = [independent_ensemble_fit.gcm_rcm_couple_to_visualizer[gcm_rcm_couple] + for independent_ensemble_fit in self.ensemble_fits(IndependentEnsembleFit) + ] + plot_histogram_all_trends_against_altitudes(self.massif_names, visualizer_list, with_significance=with_significance) + # for relative in [True, False]: + # plot_shoe_plot_changes_against_altitude(self.massif_names, visualizer_list, relative=relative) + + def ensemble_fits(self, ensemble_class): + return [ensemble_class_to_ensemble_fit[ensemble_class] + for ensemble_class_to_ensemble_fit + in self.altitude_group_to_ensemble_class_to_ensemble_fit.values()] + + def plot_together(self): + pass -- GitLab