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