From 4e372cee7a671b8f1c3e4b08554160f1d909ac68 Mon Sep 17 00:00:00 2001 From: Le Roux Erwan <erwan.le-roux@irstea.fr> Date: Wed, 8 Apr 2020 19:07:56 +0200 Subject: [PATCH] [contrasting project] add comparative_curve_wrt_altitude.py to provide box plot wrt the altitude --- .../gorman_figures/figure1/__init__.py | 0 .../figure1/comparative_curve_wrt_altitude.py | 97 +++++++++++++++++++ .../figure1_mean_ratio_return_level_ratio.py | 41 ++++++++ .../result_from_stationary_fit.py | 16 ++- ...y_visualizer_for_double_stationary_fit.py} | 24 +---- 5 files changed, 155 insertions(+), 23 deletions(-) create mode 100644 projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/__init__.py create mode 100644 projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/comparative_curve_wrt_altitude.py create mode 100644 projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/figure1_mean_ratio_return_level_ratio.py rename projects/contrasting_trends_in_snow_loads/gorman_figures/{ => figure1}/result_from_stationary_fit.py (81%) rename projects/contrasting_trends_in_snow_loads/gorman_figures/{figure1_mean_ratio_return_level_ratio.py => figure1/study_visualizer_for_double_stationary_fit.py} (85%) diff --git a/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/__init__.py b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/comparative_curve_wrt_altitude.py b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/comparative_curve_wrt_altitude.py new file mode 100644 index 00000000..610fb2d6 --- /dev/null +++ b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/comparative_curve_wrt_altitude.py @@ -0,0 +1,97 @@ +from collections import OrderedDict +import matplotlib.pyplot as plt +import numpy as np + +from cached_property import cached_property + +from projects.contrasting_trends_in_snow_loads.gorman_figures.figure1.study_visualizer_for_double_stationary_fit import \ + StudyVisualizerForReturnLevelChange + + +class ComparativeCurveWrtAltitude(object): + + def __init__(self, altitude_to_study_visualizer): + assert isinstance(altitude_to_study_visualizer, OrderedDict) + self.altitude_to_study_visualizer = altitude_to_study_visualizer # type: OrderedDict[int, StudyVisualizerForReturnLevelChange] + + @cached_property + def visualizer(self): + return list(self.altitude_to_study_visualizer.values())[0] + + @property + def altitudes(self): + return list(self.altitude_to_study_visualizer.keys()) + + def all_plots(self): + self.shape_shoe_plot() + self.return_level_shot_plot() + + def shape_shoe_plot(self): + altitude_to_list_couple = OrderedDict() + for a, v in self.altitude_to_study_visualizer.items(): + altitude_to_list_couple[a] = v.result_from_double_stationary_fit.shape_list_couple + label = 'shape parameter' + self.abstract_shoe_plot(altitude_to_list_couple, plot_name=label, ylabel=label, relative_change=False) + + def return_level_shot_plot(self): + altitude_to_list_couple = OrderedDict() + for a, v in self.altitude_to_study_visualizer.items(): + altitude_to_list_couple[a] = v.result_from_double_stationary_fit.return_level_list_couple + label = '{}-year return level ({})'.format(self.visualizer.return_period, self.visualizer.study.variable_unit) + self.abstract_shoe_plot(altitude_to_list_couple, plot_name='return level', ylabel=label) + + def abstract_shoe_plot(self, altitude_to_list_couple, plot_name, ylabel, relative_change=True): + # Prepare axis + ax = plt.gca() + ax2 = ax.twinx() + + # Prepare data + altitude_to_all_relative_differences = OrderedDict() + altitude_to_all_differences = OrderedDict() + altitude_to_mean_value_before = OrderedDict() + altitude_to_mean_value_after = OrderedDict() + for altitude in self.altitudes: + list_couple = altitude_to_list_couple[altitude] + before, after = [np.array(a) for a in zip(*list_couple)] + altitude_to_mean_value_before[altitude] = before.mean() + altitude_to_mean_value_after[altitude] = after.mean() + altitude_to_all_relative_differences[altitude] = 100 * (after - before) / before + altitude_to_all_differences[altitude] = after - before + + # ax2: Boxplot + + width = 100 + x = altitude_to_all_relative_differences if relative_change else altitude_to_all_differences + ax2.boxplot(x.values(), positions=self.altitudes, widths=width) + ax2.set_xlim([min(self.altitudes) - width, max(self.altitudes) + width]) + if relative_change: + ax2.set_ylabel('Relative change in {} (%)'.format((ylabel.split('(')[0]))) + else: + ax2.set_ylabel('Change in {}'.format(ylabel)) + + # ax: Mean plots on top + values = [list(v.values()) for v in [altitude_to_mean_value_before, altitude_to_mean_value_after]] + labels = [ + '{}-{}'.format(self.visualizer.year_min_before, self.visualizer.year_max_before), + '{}-{}'.format(self.visualizer.year_min_after, self.visualizer.year_max_after), + ] + for label, value in zip(labels, values): + ax.plot(self.altitudes, value, label=label, marker='o') + ax.set_ylabel('Mean {}'.format(ylabel)) + ax.legend(loc='upper left') # , prop={'size': size}) + ax.set_xlabel('Altitude (m)') + + # Set same limits to align axis + a = np.array(list(x.values())) + all_values = list(a.flatten()) + values[0] + values[1] + print(type(all_values)) + epsilon = 0.03 * (max(all_values) - min(all_values)) + ylim = [min(all_values) - epsilon, max(all_values) + epsilon] + ax.set_ylim(ylim) + ax2.set_ylim(ylim) + ax.grid() + + self.visualizer.plot_name = plot_name + ' summary' + self.visualizer.show_or_save_to_file(add_classic_title=False, tight_layout=True, no_title=True, + dpi=500) + plt.close() diff --git a/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/figure1_mean_ratio_return_level_ratio.py b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/figure1_mean_ratio_return_level_ratio.py new file mode 100644 index 00000000..74159dbe --- /dev/null +++ b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/figure1_mean_ratio_return_level_ratio.py @@ -0,0 +1,41 @@ +from collections import OrderedDict + +from extreme_data.meteo_france_data.scm_models_data.crocus.crocus import CrocusSnowLoad1Day, CrocusSnowLoad3Days, \ + CrocusSnowLoadTotal +from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall1Day, SafranSnowfall3Days, \ + SafranSnowfall7Days, SafranSnowfall5Days +from extreme_data.meteo_france_data.scm_models_data.visualization.main_study_visualizer import ALL_ALTITUDES_WITHOUT_NAN +from extreme_fit.model.margin_model.linear_margin_model.abstract_temporal_linear_margin_model import \ + TemporalMarginFitMethod +from projects.contrasting_trends_in_snow_loads.gorman_figures.figure1.comparative_curve_wrt_altitude import \ + ComparativeCurveWrtAltitude + +from projects.contrasting_trends_in_snow_loads.gorman_figures.figure1.study_visualizer_for_double_stationary_fit import \ + StudyVisualizerForReturnLevelChange + + +def load_altitude_to_study_visualizer(study_class, save_to_file=True) -> OrderedDict: + altitude_to_study_visualizer = OrderedDict() + # for altitude in ALL_ALTITUDES_WITHOUT_NAN[2:10]: + for altitude in ALL_ALTITUDES_WITHOUT_NAN[2:5]: + return_period = 30 + study_visualizer = StudyVisualizerForReturnLevelChange(study_class=study_class, + altitude=altitude, + return_period=return_period, + save_to_file=save_to_file, + fit_method=TemporalMarginFitMethod.extremes_fevd_l_moments) + altitude_to_study_visualizer[altitude] = study_visualizer + return altitude_to_study_visualizer + + +def plots(): + for study_class in [SafranSnowfall1Day, SafranSnowfall3Days, SafranSnowfall5Days, SafranSnowfall7Days][:1]: + altitude_to_study_visualizer = load_altitude_to_study_visualizer(study_class, save_to_file=True) + # for v in altitude_to_study_visualizer.values(): + # v.all_plots() + comparative_curve = ComparativeCurveWrtAltitude(altitude_to_study_visualizer) + comparative_curve.all_plots() + + +if __name__ == '__main__': + plots() diff --git a/projects/contrasting_trends_in_snow_loads/gorman_figures/result_from_stationary_fit.py b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/result_from_stationary_fit.py similarity index 81% rename from projects/contrasting_trends_in_snow_loads/gorman_figures/result_from_stationary_fit.py rename to projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/result_from_stationary_fit.py index 306022af..a830dfac 100644 --- a/projects/contrasting_trends_in_snow_loads/gorman_figures/result_from_stationary_fit.py +++ b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/result_from_stationary_fit.py @@ -16,6 +16,10 @@ class ResultFromDoubleStationaryFit(object): self.result_before = ResultFromSingleStationaryFit(study_before, fit_method, return_period) self.result_after = ResultFromSingleStationaryFit(study_after, fit_method, return_period) + @property + def massif_names(self): + return self.re + @cached_property def massif_name_to_difference_return_level(self): return {m: v - self.result_before.massif_name_to_return_level[m] @@ -26,6 +30,16 @@ class ResultFromDoubleStationaryFit(object): return {m: 100 * v / self.result_before.massif_name_to_return_level[m] for m, v in self.massif_name_to_difference_return_level.items()} + @cached_property + def return_level_list_couple(self): + return [(v, self.result_after.massif_name_to_return_level[m]) + for m, v in self.result_before.massif_name_to_return_level.items()] + + @cached_property + def shape_list_couple(self): + return [(v, self.result_after.massif_name_to_shape[m]) + for m, v in self.result_before.massif_name_to_shape.items()] + class ResultFromSingleStationaryFit(object): @@ -54,4 +68,4 @@ class ResultFromSingleStationaryFit(object): @property def massif_name_to_difference_return_level_and_maxima(self): - return {m: r - np.max(self.massif_name_to_maxima[m]) for m, r in self.massif_name_to_return_level.items() } + return {m: r - np.max(self.massif_name_to_maxima[m]) for m, r in self.massif_name_to_return_level.items()} diff --git a/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1_mean_ratio_return_level_ratio.py b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/study_visualizer_for_double_stationary_fit.py similarity index 85% rename from projects/contrasting_trends_in_snow_loads/gorman_figures/figure1_mean_ratio_return_level_ratio.py rename to projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/study_visualizer_for_double_stationary_fit.py index 6ff11028..144a3502 100644 --- a/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1_mean_ratio_return_level_ratio.py +++ b/projects/contrasting_trends_in_snow_loads/gorman_figures/figure1/study_visualizer_for_double_stationary_fit.py @@ -1,25 +1,19 @@ -from collections import OrderedDict - import matplotlib -import numpy as np -from cached_property import cached_property from extreme_data.meteo_france_data.scm_models_data.abstract_study import AbstractStudy from extreme_data.meteo_france_data.scm_models_data.crocus.crocus import CrocusSnowLoad1Day, CrocusSnowLoad3Days, \ CrocusSnowLoadTotal from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall1Day, SafranSnowfall3Days from extreme_data.meteo_france_data.scm_models_data.visualization.create_shifted_cmap import get_shifted_map, \ - get_colors, shiftedColorMap, ticks_values_and_labels_for_percentages + get_colors, ticks_values_and_labels_for_percentages from extreme_data.meteo_france_data.scm_models_data.visualization.main_study_visualizer import ALL_ALTITUDES_WITHOUT_NAN from extreme_data.meteo_france_data.scm_models_data.visualization.study_visualizer import StudyVisualizer -from extreme_fit.estimator.margin_estimator.utils import fitted_stationary_gev from extreme_fit.model.margin_model.linear_margin_model.abstract_temporal_linear_margin_model import \ TemporalMarginFitMethod, fitmethod_to_str import matplotlib.pyplot as plt -from extreme_trend.visualizers.study_visualizer_for_non_stationary_trends import StudyVisualizerForNonStationaryTrends -from projects.contrasting_trends_in_snow_loads.gorman_figures.result_from_stationary_fit import \ +from projects.contrasting_trends_in_snow_loads.gorman_figures.figure1.result_from_stationary_fit import \ ResultFromDoubleStationaryFit @@ -161,17 +155,3 @@ class StudyVisualizerForReturnLevelChange(StudyVisualizer): ax.set_xticks([]) ax.set_xlabel('Altitude = {}m'.format(self.study.altitude), fontsize=15) ax.set_title('Fit method is {}'.format(fitmethod_to_str(self.fit_method))) - - -if __name__ == '__main__': - # for altitude in [900, 1200, 1500, 1800, 2100, 2400, 2700, 3000][:1]: - for altitude in ALL_ALTITUDES_WITHOUT_NAN: - for study_class in [SafranSnowfall1Day, SafranSnowfall3Days, CrocusSnowLoadTotal, CrocusSnowLoad3Days, - CrocusSnowLoad1Day][:1]: - return_period = 30 - study_visualizer = StudyVisualizerForReturnLevelChange(study_class=study_class, - altitude=altitude, - return_period=return_period, - save_to_file=True, - fit_method=TemporalMarginFitMethod.extremes_fevd_l_moments) - study_visualizer.all_plots() -- GitLab