Newer
Older
Le Roux Erwan
committed
import matplotlib.pyplot as plt
from collections import OrderedDict
Le Roux Erwan
committed
from typing import List
Le Roux Erwan
committed
from extreme_data.meteo_france_data.adamont_data.adamont_gcm_rcm_couples import gcm_rcm_couple_to_color
from extreme_data.meteo_france_data.adamont_data.adamont_scenario import gcm_rcm_couple_to_str
from extreme_data.meteo_france_data.scm_models_data.abstract_study import AbstractStudy
from extreme_fit.distribution.gev.gev_params import GevParams
from extreme_fit.model.margin_model.polynomial_margin_model.spatio_temporal_polynomial_model import \
AbstractSpatioTemporalPolynomialModel
from extreme_fit.model.margin_model.utils import MarginFitMethod
Le Roux Erwan
committed
from extreme_data.meteo_france_data.scm_models_data.altitudes_studies import AltitudesStudies
Le Roux Erwan
committed
from extreme_trend.ensemble_fit.abstract_ensemble_fit import AbstractEnsembleFit
from extreme_trend.ensemble_fit.independent_ensemble_fit.independent_ensemble_fit import IndependentEnsembleFit
Le Roux Erwan
committed
from extreme_trend.ensemble_fit.together_ensemble_fit.together_ensemble_fit import TogetherEnsembleFit
from extreme_trend.one_fold_fit.altitude_group import get_altitude_class_from_altitudes
from extreme_trend.one_fold_fit.plots.plot_histogram_altitude_studies import \
Le Roux Erwan
committed
plot_histogram_all_trends_against_altitudes, plot_shoe_plot_changes_against_altitude
from extreme_trend.one_fold_fit.utils_altitude_studies_visualizer import compute_and_assign_max_abs
class VisualizerForProjectionEnsemble(object):
Le Roux Erwan
committed
def __init__(self, altitudes_list, gcm_rcm_couples, study_class, season, scenario,
model_classes: List[AbstractSpatioTemporalPolynomialModel],
ensemble_fit_classes=None,
massif_names=None,
fit_method=MarginFitMethod.extremes_fevd_mle,
temporal_covariate_for_fit=None,
display_only_model_that_pass_gof_test=False,
Le Roux Erwan
committed
confidence_interval_based_on_delta_method=False,
remove_physically_implausible_models=False,
gcm_to_year_min_and_year_max=None,
self.altitudes_list = altitudes_list
Le Roux Erwan
committed
self.temporal_covariate_for_fit = temporal_covariate_for_fit
Le Roux Erwan
committed
self.scenario = scenario
Le Roux Erwan
committed
self.gcm_rcm_couples = gcm_rcm_couples
self.massif_names = massif_names
self.ensemble_fit_classes = ensemble_fit_classes
Le Roux Erwan
committed
# Some checks
if gcm_to_year_min_and_year_max is not None:
for gcm, years in gcm_to_year_min_and_year_max.items():
assert isinstance(gcm, str), gcm
assert len(years) == 2, years
Le Roux Erwan
committed
# Load all studies
altitude_class_to_gcm_couple_to_studies = OrderedDict()
Le Roux Erwan
committed
for altitudes in altitudes_list:
altitude_class = get_altitude_class_from_altitudes(altitudes)
Le Roux Erwan
committed
gcm_rcm_couple_to_studies = {}
for gcm_rcm_couple in gcm_rcm_couples:
if gcm_to_year_min_and_year_max is None:
kwargs_study = {}
else:
gcm = gcm_rcm_couple[0]
if gcm not in gcm_to_year_min_and_year_max:
# It means that for this gcm and scenario,
# there is not enough data (less than 30 years) for the fit
continue
year_min, year_max = gcm_to_year_min_and_year_max[gcm]
kwargs_study = {'year_min': year_min, 'year_max': year_max}
Le Roux Erwan
committed
studies = AltitudesStudies(study_class, altitudes, season=season,
scenario=scenario, gcm_rcm_couple=gcm_rcm_couple,
**kwargs_study)
Le Roux Erwan
committed
gcm_rcm_couple_to_studies[gcm_rcm_couple] = studies
if len(gcm_rcm_couple_to_studies) == 0:
print('No valid studies for the following couples:', self.gcm_rcm_couples)
altitude_class_to_gcm_couple_to_studies[altitude_class] = gcm_rcm_couple_to_studies
Le Roux Erwan
committed
# Load ensemble fit
self.altitude_class_to_ensemble_class_to_ensemble_fit = OrderedDict()
for altitude_class, gcm_rcm_couple_to_studies in altitude_class_to_gcm_couple_to_studies.items():
Le Roux Erwan
committed
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,
Le Roux Erwan
committed
confidence_interval_based_on_delta_method,
remove_physically_implausible_models)
Le Roux Erwan
committed
ensemble_class_to_ensemble_fit[ensemble_fit_class] = ensemble_fit
self.altitude_class_to_ensemble_class_to_ensemble_fit[altitude_class] = ensemble_class_to_ensemble_fit
Le Roux Erwan
committed
Le Roux Erwan
committed
def plot_for_visualizer_list(self, visualizer_list):
with_significance = False
for v in visualizer_list:
v.plot_moments()
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,
with_significance=with_significance)
Le Roux Erwan
committed
def plot(self):
Le Roux Erwan
committed
# Set limit for the plot
visualizer_list = []
for ensemble_fit_class in self.ensemble_fit_classes:
for ensemble_fit in self.ensemble_fits(ensemble_fit_class):
visualizer_list.extend(ensemble_fit.visualizer_list)
compute_and_assign_max_abs(visualizer_list)
# Plot
Le Roux Erwan
committed
if IndependentEnsembleFit in self.ensemble_fit_classes:
self.plot_independent()
Le Roux Erwan
committed
if TogetherEnsembleFit in self.ensemble_fit_classes:
self.plot_together()
Le Roux Erwan
committed
def plot_independent(self):
Le Roux Erwan
committed
# Aggregated at gcm_rcm_level plots
Le Roux Erwan
committed
merge_keys = [AbstractEnsembleFit.Median_merge, AbstractEnsembleFit.Mean_merge]
keys = self.gcm_rcm_couples + merge_keys
# Only plot Mean for speed
Le Roux Erwan
committed
keys = [AbstractEnsembleFit.Mean_merge]
for key in keys:
visualizer_list = [independent_ensemble_fit.gcm_rcm_couple_to_visualizer[key]
if key in self.gcm_rcm_couples
else independent_ensemble_fit.merge_function_name_to_visualizer[key]
Le Roux Erwan
committed
for independent_ensemble_fit in self.ensemble_fits(IndependentEnsembleFit)
]
if key in merge_keys:
Le Roux Erwan
committed
for v in visualizer_list:
v.studies.study.gcm_rcm_couple = (key, "merge")
Le Roux Erwan
committed
self.plot_for_visualizer_list(visualizer_list)
def plot_together(self):
visualizer_list = [together_ensemble_fit.visualizer
for together_ensemble_fit in self.ensemble_fits(TogetherEnsembleFit)]
Le Roux Erwan
committed
for v in visualizer_list:
v.studies.study.gcm_rcm_couple = ("together", "merge")
Le Roux Erwan
committed
self.plot_for_visualizer_list(visualizer_list)
Le Roux Erwan
committed
def ensemble_fits(self, ensemble_class):
"""Return the ordered ensemble fit for a given ensemble class (in the order of the altitudes)"""
Le Roux Erwan
committed
return [ensemble_class_to_ensemble_fit[ensemble_class]
for ensemble_class_to_ensemble_fit
in self.altitude_class_to_ensemble_class_to_ensemble_fit.values()]
Le Roux Erwan
committed
def plot_preliminary_first_part(self):
if self.massif_names is None:
massif_names = AbstractStudy.all_massif_names()
else:
massif_names = self.massif_names
assert isinstance(massif_names, list)
# Plot for all parameters
for param_name in GevParams.PARAM_NAMES:
for degree in [0, 1]:
for massif_name in massif_names:
self.plot_preliminary_first_part_for_one_massif(massif_name, param_name, degree)
def plot_preliminary_first_part_for_one_massif(self, massif_name, param_name, degree):
# Retrieve the data
ensemble_fit: IndependentEnsembleFit
gcm_rcm_couple_to_data = {
c: [] for c in self.gcm_rcm_couples
}
for ensemble_fit in self.ensemble_fits(IndependentEnsembleFit):
for gcm_rcm_couple in self.gcm_rcm_couples:
visualizer = ensemble_fit.gcm_rcm_couple_to_visualizer[gcm_rcm_couple]
if massif_name in visualizer.massif_name_to_one_fold_fit:
one_fold_fit = visualizer.massif_name_to_one_fold_fit[massif_name]
coef = one_fold_fit.best_coef(param_name, 0, degree)
altitude = visualizer.altitude_group.reference_altitude
gcm_rcm_couple_to_data[gcm_rcm_couple].append((altitude, coef))
Le Roux Erwan
committed
# Plot
ax = plt.gca()
for gcm_rcm_couple, data in gcm_rcm_couple_to_data.items():
altitudes, coefs = list(zip(*data))
color = gcm_rcm_couple_to_color[gcm_rcm_couple]
label = gcm_rcm_couple_to_str(gcm_rcm_couple)
ax.plot(coefs, altitudes, color=color, label=label, marker='o')
ax.legend()
visualizer.plot_name = '{}/{}_{}'.format(param_name, degree, massif_name)
visualizer.show_or_save_to_file(no_title=True)
plt.close()