Commit 5a5e2554 authored by Le Roux Erwan's avatar Le Roux Erwan
Browse files

[METEO FRANCE DATA] add gev visualization in comparisons_visualization

parent bdc474d6
No related merge requests found
Showing with 74 additions and 27 deletions
+74 -27
...@@ -246,7 +246,8 @@ class ComparisonAnalysis(object): ...@@ -246,7 +246,8 @@ class ComparisonAnalysis(object):
df_study = pd.concat([df, df_coord, df_obs], axis=1) df_study = pd.concat([df, df_coord, df_obs], axis=1)
return df_study return df_study
def load_main_df_merged_intersection_clean(self): @cached_property
def df_merged_intersection_clean(self):
df_stations = self.load_main_df_station_intersection_clean() df_stations = self.load_main_df_station_intersection_clean()
df_study = self.load_main_df_study_intersection_clean() df_study = self.load_main_df_study_intersection_clean()
diff = set(df_study.columns).symmetric_difference(set(df_stations.columns)) diff = set(df_study.columns).symmetric_difference(set(df_stations.columns))
......
...@@ -5,22 +5,30 @@ from experiment.meteo_france_data.stations_data.visualization.comparisons_visual ...@@ -5,22 +5,30 @@ from experiment.meteo_france_data.stations_data.visualization.comparisons_visual
ComparisonsVisualization ComparisonsVisualization
def visualize_full_comparison(): def visualize_all_stations():
vizu = ComparisonsVisualization(altitudes=ALL_ALTITUDES_WITH_20_STATIONS_AT_LEAST, margin=150) vizu = ComparisonsVisualization(altitudes=ALL_ALTITUDES_WITH_20_STATIONS_AT_LEAST, margin=150)
vizu.visualize_maximum() vizu.visualize_maximum()
def visualize_fast_comparison(): def visualize_non_nan_station():
vizu = ComparisonsVisualization(altitudes=[900]) vizu = ComparisonsVisualization(altitudes=ALL_ALTITUDES_WITH_20_STATIONS_AT_LEAST,
vizu.visualize_maximum() keep_only_station_without_nan_values=True,
normalize_observations=True)
# vizu.visualize_maximum()
vizu.visualize_gev()
def example(): def example():
vizu = ComparisonsVisualization(altitudes=[900]) # this is a really good example for the maxima at least
vizu._visualize_maximum(vizu.comparisons[0], 'Beaufortain', show=True) vizu = ComparisonsVisualization(altitudes=[900], normalize_observations=False)
vizu._visualize_ax_main(vizu.plot_maxima, vizu.comparisons[0], 'Beaufortain', show=True)
# vizu = ComparisonsVisualization(altitudes=[900], normalize_observations=False, keep_only_station_without_nan_values=True)
# vizu._visualize_ax_main(vizu.plot_gev, vizu.comparisons[0], 'Beaufortain', show=True)
if __name__ == '__main__': if __name__ == '__main__':
# visualize_fast_comparison() # visualize_fast_comparison()
visualize_full_comparison() # visualize_all_stations()
visualize_non_nan_station()
# example() # example()
from itertools import chain
from typing import Dict, List from typing import Dict, List
import math import math
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np
import pandas as pd import pandas as pd
from experiment.meteo_france_data.scm_models_data.visualization.study_visualization.study_visualizer import \ from experiment.meteo_france_data.scm_models_data.visualization.study_visualization.study_visualizer import \
VisualizationParameters VisualizationParameters
from experiment.meteo_france_data.stations_data.comparison_analysis import ComparisonAnalysis, MASSIF_COLUMN_NAME, \ from experiment.meteo_france_data.stations_data.comparison_analysis import ComparisonAnalysis, MASSIF_COLUMN_NAME, \
REANALYSE_STR, ALTITUDE_COLUMN_NAME REANALYSE_STR, ALTITUDE_COLUMN_NAME
from itertools import chain from extreme_estimator.extreme_models.result_from_fit import ResultFromIsmev
from extreme_estimator.extreme_models.utils import r, safe_run_r_estimator, ro
class ComparisonsVisualization(VisualizationParameters): class ComparisonsVisualization(VisualizationParameters):
def __init__(self, altitudes=None, keep_only_station_without_nan_values=False, margin=150): def __init__(self, altitudes=None, keep_only_station_without_nan_values=False, margin=150,
normalize_observations=False):
self.keep_only_station_without_nan_values = keep_only_station_without_nan_values self.keep_only_station_without_nan_values = keep_only_station_without_nan_values
if self.keep_only_station_without_nan_values: if self.keep_only_station_without_nan_values:
self.nb_columns = 5 self.nb_columns = 5
...@@ -24,7 +28,7 @@ class ComparisonsVisualization(VisualizationParameters): ...@@ -24,7 +28,7 @@ class ComparisonsVisualization(VisualizationParameters):
self.altitude_to_comparison = {} # type: Dict[int, ComparisonAnalysis] self.altitude_to_comparison = {} # type: Dict[int, ComparisonAnalysis]
for altitude in altitudes: for altitude in altitudes:
comparison = ComparisonAnalysis(altitude=altitude, comparison = ComparisonAnalysis(altitude=altitude,
normalize_observations=False, normalize_observations=normalize_observations,
one_station_per_massif=False, one_station_per_massif=False,
transformation_class=None, transformation_class=None,
margin=margin, margin=margin,
...@@ -43,7 +47,7 @@ class ComparisonsVisualization(VisualizationParameters): ...@@ -43,7 +47,7 @@ class ComparisonsVisualization(VisualizationParameters):
def massifs(self): def massifs(self):
return sorted(set(chain(*[c.intersection_massif_names for c in self.comparisons]))) return sorted(set(chain(*[c.intersection_massif_names for c in self.comparisons])))
def _visualize_main(self, visualization_ax_function, title=''): def _visualize_main(self, plot_function, title=''):
nb_rows = math.ceil(self.nb_plot / self.nb_columns) nb_rows = math.ceil(self.nb_plot / self.nb_columns)
fig, axes = plt.subplots(nb_rows, self.nb_columns, figsize=self.figsize) fig, axes = plt.subplots(nb_rows, self.nb_columns, figsize=self.figsize)
fig.subplots_adjust(hspace=self.subplot_space, wspace=self.subplot_space) fig.subplots_adjust(hspace=self.subplot_space, wspace=self.subplot_space)
...@@ -52,39 +56,54 @@ class ComparisonsVisualization(VisualizationParameters): ...@@ -52,39 +56,54 @@ class ComparisonsVisualization(VisualizationParameters):
ax_idx = 0 ax_idx = 0
for massif in self.massifs: for massif in self.massifs:
for c in [c for c in self.comparisons if massif in c.intersection_massif_names]: for c in [c for c in self.comparisons if massif in c.intersection_massif_names]:
visualization_ax_function(c, massif, axes[ax_idx]) self._visualize_ax_main(plot_function, c, massif, axes[ax_idx])
ax_idx += 1 ax_idx += 1
plt.suptitle(title) plt.suptitle(title)
plt.show() plt.show()
def visualize_maximum(self): def _visualize_ax_main(self, plot_function, comparison: ComparisonAnalysis, massif, ax=None, show=False):
return self._visualize_main(self._visualize_maximum, 'Recent trend of Annual maxima of snowfall')
def _visualize_maximum(self, comparison: ComparisonAnalysis, massif, ax=None, show=False):
if ax is None: if ax is None:
_, ax = plt.subplots(1, 1, figsize=self.figsize) _, ax = plt.subplots(1, 1, figsize=self.figsize)
df = comparison.load_main_df_merged_intersection_clean() df = comparison.df_merged_intersection_clean.copy()
ind = df[MASSIF_COLUMN_NAME] == massif ind = df[MASSIF_COLUMN_NAME] == massif
df.drop([MASSIF_COLUMN_NAME], axis=1, inplace=True) df.drop([MASSIF_COLUMN_NAME], axis=1, inplace=True)
assert sum(ind) > 0 assert sum(ind) > 0
df = df.loc[ind] # type: pd.DataFrame df = df.loc[ind] # type: pd.DataFrame
colors_station = ['r', 'tab:orange', 'tab:purple', 'm', 'k'] colors_station = ['r', 'tab:orange', 'tab:purple', 'm', 'k']
for color, (i, s) in zip(colors_station, df.iterrows()): for color, (i, s) in zip(colors_station, df.iterrows()):
label = i label = i
label += ' ({}m)'.format(s[ALTITUDE_COLUMN_NAME]) label += ' ({}m)'.format(s[ALTITUDE_COLUMN_NAME])
s_values = s.iloc[3:].to_dict() s_values = s.iloc[3:].to_dict()
plot_color = color if REANALYSE_STR not in label else 'g' plot_color = color if REANALYSE_STR not in label else 'g'
ax.plot(list(s_values.keys()), list(s_values.values()), label=label, color=plot_color) plot_function(ax, s_values, label, plot_color)
ax.legend(prop={'size': 5})
ax.set_title('{} at {}'.format(massif, comparison.altitude)) ax.set_title('{} at {}'.format(massif, comparison.altitude))
ax.legend(prop={'size': 5})
if show: if show:
plt.show() plt.show()
def visualize_maximum(self):
return self._visualize_main(self.plot_maxima, 'Recent trend of Annual maxima of snowfall')
def plot_maxima(self, ax, s_values, label, plot_color):
ax.plot(list(s_values.keys()), list(s_values.values()), label=label, color=plot_color)
def visualize_gev(self): def visualize_gev(self):
return self._visualize_main(self._visualize_gev) return self._visualize_main(self.plot_gev)
def plot_gev(self, ax, s_values, label, plot_color):
# todo should I normalize here ?
# fit gev
data = list(s_values.values())
res = safe_run_r_estimator(function=r('gev.fit'), xdat=ro.FloatVector(data),
use_start=True)
res = ResultFromIsmev(res, {})
gev_params = res.stationary_gev_params
lim = 1.5 * max(data)
x = np.linspace(0, lim, 1000)
y = gev_params.density(x)
# display the gev distribution that was obtained
ax.plot(x, y, label=label, color=plot_color)
def _visualize_gev(self):
pass
...@@ -11,6 +11,7 @@ from spatio_temporal_dataset.coordinates.abstract_coordinates import AbstractCoo ...@@ -11,6 +11,7 @@ from spatio_temporal_dataset.coordinates.abstract_coordinates import AbstractCoo
def convertFloatVector_to_float(f): def convertFloatVector_to_float(f):
return np.array(f)[0] return np.array(f)[0]
class ResultFromFit(object): class ResultFromFit(object):
def __init__(self, result_from_fit: robjects.ListVector) -> None: def __init__(self, result_from_fit: robjects.ListVector) -> None:
...@@ -74,6 +75,12 @@ class ResultFromIsmev(ResultFromFit): ...@@ -74,6 +75,12 @@ class ResultFromIsmev(ResultFromFit):
i += 1 i += 1
return coef_dict return coef_dict
@property
def stationary_gev_params(self) -> GevParams:
params = {k.split('Coeff1')[0]: v for k, v in self.margin_coef_dict.items()
if 'Coeff1' in k and 'temp' not in k}
return GevParams.from_dict(params)
@property @property
def all_parameters(self): def all_parameters(self):
return self.margin_coef_dict return self.margin_coef_dict
...@@ -91,7 +98,6 @@ class ResultFromIsmev(ResultFromFit): ...@@ -91,7 +98,6 @@ class ResultFromIsmev(ResultFromFit):
return convertFloatVector_to_float(self.name_to_value['conv']) == 0 return convertFloatVector_to_float(self.name_to_value['conv']) == 0
class ResultFromSpatialExtreme(ResultFromFit): class ResultFromSpatialExtreme(ResultFromFit):
""" """
Handler from any result with the result of a fit functions from the package Spatial Extreme Handler from any result with the result of a fit functions from the package Spatial Extreme
......
...@@ -21,9 +21,22 @@ class GevParams(ExtremeParams): ...@@ -21,9 +21,22 @@ class GevParams(ExtremeParams):
else: else:
return r.qgev(p, self.location, self.scale, self.shape)[0] return r.qgev(p, self.location, self.scale, self.shape)[0]
def density(self, x):
if self.has_undefined_parameters:
return np.nan
else:
res = r.dgev(x, self.location, self.scale, self.shape)
if isinstance(x, float):
return res[0]
else:
return np.array(res)
@property @property
def param_values(self): def param_values(self):
if self.has_undefined_parameters: if self.has_undefined_parameters:
return [np.nan for _ in range(3)] return [np.nan for _ in range(3)]
else: else:
return [self.location, self.scale, self.shape] return [self.location, self.scale, self.shape]
\ No newline at end of file
def __str__(self):
return self.to_dict().__str__()
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment