From ef98837860cf795aec2be3d1baf138700dc11ad5 Mon Sep 17 00:00:00 2001 From: Le Roux Erwan <erwan.le-roux@irstea.fr> Date: Tue, 26 Feb 2019 11:17:53 +0100 Subject: [PATCH] [SCM] improve empirical distribution visualization for slides. add single_massif_graph visualization --- .../meteo_france_SCM_study/main_visualize.py | 6 +-- .../safran/safran_visualizer.py | 45 +++++++++++-------- .../abstract_margin_function.py | 11 ++++- .../margin_fits/abstract_params.py | 7 +-- .../test_extreme_models/test_margin_model.py | 44 +++++++++++++----- 5 files changed, 77 insertions(+), 36 deletions(-) diff --git a/experiment/meteo_france_SCM_study/main_visualize.py b/experiment/meteo_france_SCM_study/main_visualize.py index 2cf6622d..180ea81b 100644 --- a/experiment/meteo_france_SCM_study/main_visualize.py +++ b/experiment/meteo_france_SCM_study/main_visualize.py @@ -33,9 +33,9 @@ def study_iterator(study_class, only_first_one=False, both_altitude=False, verbo def extended_visualization(): - for study_class in SCM_EXTENDED_STUDIES[-1:]: - for study in study_iterator(study_class, only_first_one=True): - study_visualizer = StudyVisualizer(study) + for study_class in SCM_EXTENDED_STUDIES[:]: + for study in study_iterator(study_class, only_first_one=False): + study_visualizer = StudyVisualizer(study, single_massif_graph=True, save_to_file=True) # study_visualizer.visualize_all_kde_graphs() study_visualizer.visualize_all_experimental_law() diff --git a/experiment/meteo_france_SCM_study/safran/safran_visualizer.py b/experiment/meteo_france_SCM_study/safran/safran_visualizer.py index 90ac03a8..8e3b0f91 100644 --- a/experiment/meteo_france_SCM_study/safran/safran_visualizer.py +++ b/experiment/meteo_france_SCM_study/safran/safran_visualizer.py @@ -28,7 +28,8 @@ from utils import get_display_name_from_object_type, VERSION_TIME, float_to_str_ class StudyVisualizer(object): - def __init__(self, study: AbstractStudy, show=True, save_to_file=False): + def __init__(self, study: AbstractStudy, show=True, save_to_file=False, single_massif_graph=False): + self.single_massif_graph = single_massif_graph self.save_to_file = save_to_file self.study = study self.show = False if self.save_to_file else show @@ -50,18 +51,22 @@ class StudyVisualizer(object): # Graph for each massif / or groups of massifs def visualize_massif_graphs(self, visualize_function): - nb_columns = 5 - nb_rows = math.ceil(len(self.study.safran_massif_names) / nb_columns) - fig, axes = plt.subplots(nb_rows, nb_columns, figsize=self.figsize) - fig.subplots_adjust(hspace=1.0, wspace=1.0) - for massif_id, massif_name in enumerate(self.study.safran_massif_names): - row_id, column_id = massif_id // nb_columns, massif_id % nb_columns - ax = axes[row_id, column_id] - visualize_function(ax, massif_id) + if self.single_massif_graph: + fig, ax = plt.subplots(1, 1, figsize=self.figsize) + visualize_function(ax, 0) + else: + nb_columns = 5 + nb_rows = math.ceil(len(self.study.safran_massif_names) / nb_columns) + fig, axes = plt.subplots(nb_rows, nb_columns, figsize=self.figsize) + fig.subplots_adjust(hspace=1.0, wspace=1.0) + for massif_id, massif_name in enumerate(self.study.safran_massif_names): + row_id, column_id = massif_id // nb_columns, massif_id % nb_columns + ax = axes[row_id, column_id] + visualize_function(ax, massif_id) def visualize_all_experimental_law(self): self.visualize_massif_graphs(self.visualize_experimental_law) - plot_name = ' Experimental law with all the data' + plot_name = ' Empirical distribution with all available data' self.show_or_save_to_file(plot_name) def visualize_experimental_law(self, ax, massif_id): @@ -76,24 +81,26 @@ class StudyVisualizer(object): # Plot the mean point in green x_level_to_color = { - np.mean(all_massif_data): 'g', + np.mean(all_massif_data): ('g', 'mean'), } - # Plot some specific quantiles in red - for p in AbstractParams.QUANTILE_P_VALUES: + # Plot some specific quantiles in their color + for p, color, name in zip(AbstractParams.QUANTILE_P_VALUES, AbstractParams.QUANTILE_COLORS, AbstractParams.QUANTILE_NAMES): x_level = all_massif_data[int(p * len(all_massif_data))] - x_level_to_color[x_level] = 'r' + x_level_to_color[x_level] = (color, name) - for xi, color in x_level_to_color.items(): + for xi, (color, name) in x_level_to_color.items(): yi = np.interp(xi, data_x, data_y) - ax.plot([xi], [yi], color=color, marker="o") + ax.scatter([xi], [yi], color=color, marker="o", label=name) - ax.set_ylabel('Density', color=color_kde) - ax.set_xlabel(self.study.title) + ax.set_ylabel('Probability Density function f(x)', color=color_kde) + ax.set_xlabel('x = {}'.format(self.study.title)) extraticks = [float(float_to_str_with_only_some_significant_digits(x, nb_digits=2)) for x in sorted(list(x_level_to_color.keys()))] - extraticks = [extraticks[0], extraticks[-1]] + if not self.single_massif_graph: + extraticks = [extraticks[0], extraticks[-1]] ax.set_xticks(extraticks) ax.set_title(self.study.safran_massif_names[massif_id]) + ax.legend() def visualize_all_mean_and_max_graphs(self): self.visualize_massif_graphs(self.visualize_mean_and_max_graph) diff --git a/extreme_estimator/extreme_models/margin_model/margin_function/abstract_margin_function.py b/extreme_estimator/extreme_models/margin_model/margin_function/abstract_margin_function.py index cc1ac24b..a88c4beb 100644 --- a/extreme_estimator/extreme_models/margin_model/margin_function/abstract_margin_function.py +++ b/extreme_estimator/extreme_models/margin_model/margin_function/abstract_margin_function.py @@ -78,8 +78,10 @@ class AbstractMarginFunction(object): self.visualize_1D(gev_value_name, ax, show) elif self.coordinates.nb_coordinates_spatial == 2: self.visualize_2D(gev_value_name, ax, show) + elif self.coordinates.nb_coordinates_spatial == 3: + self.visualize_3D(gev_value_name, ax, show) else: - raise NotImplementedError('3D Margin visualization not yet implemented') + raise NotImplementedError('Other visualization not yet implemented') # Visualization 1D @@ -159,3 +161,10 @@ class AbstractMarginFunction(object): grid = {value_name: np.array([g[value_name] for g in grid]).reshape([resolution, resolution]) for value_name in GevParams.SUMMARY_NAMES} return grid + + # Visualization 3D + + def visualize_3D(self, gev_param_name=GevParams.LOC, ax=None, show=True): + # Make the first/the last time step 2D visualization side by side + # self.visualize_2D(gev_param_name=gev_param_name, ax=ax, show=show) + pass diff --git a/extreme_estimator/margin_fits/abstract_params.py b/extreme_estimator/margin_fits/abstract_params.py index 659aa06d..338b4b8d 100644 --- a/extreme_estimator/margin_fits/abstract_params.py +++ b/extreme_estimator/margin_fits/abstract_params.py @@ -8,11 +8,12 @@ class AbstractParams(object): # Parameters PARAM_NAMES = [] # Quantile - QUANTILE_10 = 'quantile 10' - QUANTILE_100 = 'quantile 100' - QUANTILE_1000 = 'quantile 1000' + QUANTILE_10 = 'quantile 0.9' + QUANTILE_100 = 'quantile 0.99' + QUANTILE_1000 = 'quantile 0.999' QUANTILE_NAMES = [QUANTILE_10, QUANTILE_100, QUANTILE_1000][:-1] QUANTILE_P_VALUES = [0.9, 0.99, 0.999][:-1] + QUANTILE_COLORS = ['orange', 'red', 'darkviolet'] # Summary SUMMARY_NAMES = PARAM_NAMES + QUANTILE_NAMES diff --git a/test/test_extreme_estimator/test_extreme_models/test_margin_model.py b/test/test_extreme_estimator/test_extreme_models/test_margin_model.py index 7611f024..1be2e00e 100644 --- a/test/test_extreme_estimator/test_extreme_models/test_margin_model.py +++ b/test/test_extreme_estimator/test_extreme_models/test_margin_model.py @@ -1,29 +1,53 @@ import unittest +from extreme_estimator.extreme_models.margin_model.margin_function.linear_margin_function import LinearMarginFunction from extreme_estimator.margin_fits.gev.gev_params import GevParams from extreme_estimator.extreme_models.margin_model.smooth_margin_model import LinearShapeDim1MarginModel, \ LinearAllParametersAllDimsMarginModel -from spatio_temporal_dataset.coordinates.spatial_coordinates.generated_spatial_coordinates import CircleSpatialCoordinates +from spatio_temporal_dataset.coordinates.spatial_coordinates.generated_spatial_coordinates import \ + CircleSpatialCoordinates from spatio_temporal_dataset.coordinates.spatial_coordinates.coordinates_1D import LinSpaceSpatialCoordinates +from test.test_utils import load_test_spatiotemporal_coordinates class VisualizationMarginModel(unittest.TestCase): DISPLAY = False nb_points = 2 - margin_model = [LinearShapeDim1MarginModel, LinearAllParametersAllDimsMarginModel][-1] + margin_model_class = [LinearShapeDim1MarginModel, LinearAllParametersAllDimsMarginModel][-1] - def test_example_visualization_2D(self): - spatial_coordinates = CircleSpatialCoordinates.from_nb_points(nb_points=self.nb_points) - margin_model = self.margin_model(coordinates=spatial_coordinates) - if self.DISPLAY: - margin_model.margin_function_sample.visualize_function() + def tearDown(self) -> None: + self.margin_model.margin_function_sample.visualize_function(show=self.DISPLAY) + self.assertTrue(True) def test_example_visualization_1D(self): coordinates = LinSpaceSpatialCoordinates.from_nb_points(nb_points=self.nb_points) - margin_model = self.margin_model(coordinates=coordinates, params_sample={(GevParams.SHAPE, 1): 0.02}) - margin_model.margin_function_sample.visualize_function(show=self.DISPLAY) - self.assertTrue(True) + self.margin_model = self.margin_model_class(coordinates=coordinates, params_sample={(GevParams.SHAPE, 1): 0.02}) + + def test_example_visualization_2D_spatial(self): + spatial_coordinates = CircleSpatialCoordinates.from_nb_points(nb_points=self.nb_points) + self.margin_model = self.margin_model_class(coordinates=spatial_coordinates) + + # def test_example_visualization_2D_spatio_temporal(self): + # self.nb_steps = 2 + # coordinates = load_test_spatiotemporal_coordinates(nb_steps=self.nb_steps, nb_points=self.nb_points)[0] + # self.margin_model = self.margin_model_class(coordinates) + # + # # Load margin function from coef dict + # coef_dict = {'locCoeff1': 0, 'locCoeff2': 1, 'scaleCoeff1': 0, + # 'scaleCoeff2': 1, 'shapeCoeff1': 0, + # 'shapeCoeff2': 1, + # 'tempCoeffLoc1': 1, 'tempCoeffScale1': 1, + # 'tempCoeffShape1': 1} + # margin_function = LinearMarginFunction.from_coef_dict(coordinates, + # self.margin_model.margin_function_sample.gev_param_name_to_linear_dims, + # coef_dict) + # self.margin_model.margin_function_sample = margin_function + # self.margin_model.margin_function_sample.visualize_2D(show=True) + # + # # Load if __name__ == '__main__': unittest.main() + # v = VisualizationMarginModel() + # v.test_example_visualization_2D_spatio_temporal() -- GitLab