From a6ade55970dfd3b9ad16d3174d3a69fc8ed81cea Mon Sep 17 00:00:00 2001
From: Le Roux Erwan <erwan.le-roux@irstea.fr>
Date: Mon, 27 Apr 2020 18:02:05 +0200
Subject: [PATCH] [contrasting] improve plot for temperature when maxima happen
 for the final meeting

---
 .../scm_models_data/safran/safran_variable.py |  2 +-
 .../scm_models_data/utils.py                  |  7 ++
 ...fraction.py => daily_snowfall_fraction.py} | 37 ++++++----
 .../temperature_of_snowfall_maxima.py         | 69 +++++++++++++++++++
 .../temperature_of_snowfall_maxima.py         | 35 ----------
 5 files changed, 99 insertions(+), 51 deletions(-)
 rename projects/contrasting_trends_in_snow_loads/gorman_figures/{figure  3/figure3_daily snowfall fraction.py => daily_snowfall_fraction.py} (80%)
 create mode 100644 projects/contrasting_trends_in_snow_loads/gorman_figures/temperature_of_snowfall_maxima.py
 delete mode 100644 projects/contrasting_trends_in_snow_loads/temperature_of_snowfall_maxima.py

diff --git a/extreme_data/meteo_france_data/scm_models_data/safran/safran_variable.py b/extreme_data/meteo_france_data/scm_models_data/safran/safran_variable.py
index 55d8d7b5..b1966f5d 100644
--- a/extreme_data/meteo_france_data/scm_models_data/safran/safran_variable.py
+++ b/extreme_data/meteo_france_data/scm_models_data/safran/safran_variable.py
@@ -126,7 +126,7 @@ class SafranNormalizedPrecipitationRateOnWetDaysVariable(SafranNormalizedPrecipi
 
 class SafranTemperatureVariable(AbstractVariable):
     NAME = 'Temperature'
-    UNIT = 'Celsius Degrees'
+    UNIT = '$^oC$'
 
     @classmethod
     def keyword(cls):
diff --git a/extreme_data/meteo_france_data/scm_models_data/utils.py b/extreme_data/meteo_france_data/scm_models_data/utils.py
index 3f1c57e9..97c8c2ea 100644
--- a/extreme_data/meteo_france_data/scm_models_data/utils.py
+++ b/extreme_data/meteo_france_data/scm_models_data/utils.py
@@ -11,6 +11,7 @@ WP_PATTERN_MAX_YEAR = 2008
 alps_massif_order = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30]
 pyrenees_massif_order = [64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91]
 
+
 def date_to_str(date: datetime) -> str:
     return str(date).split()[0]
 
@@ -21,6 +22,12 @@ class SeasonForTheMaxima(Enum):
     # i could add the classical seasons if needed
 
 
+def season_to_str(season):
+    season_name = str(season).split('.')[-1]
+    season_name = ' '.join(season_name.split('_'))
+    return season_name
+
+
 class FrenchRegion(Enum):
     alps = 1
     pyrenees = 2
diff --git a/projects/contrasting_trends_in_snow_loads/gorman_figures/figure  3/figure3_daily snowfall fraction.py b/projects/contrasting_trends_in_snow_loads/gorman_figures/daily_snowfall_fraction.py
similarity index 80%
rename from projects/contrasting_trends_in_snow_loads/gorman_figures/figure  3/figure3_daily snowfall fraction.py
rename to projects/contrasting_trends_in_snow_loads/gorman_figures/daily_snowfall_fraction.py
index 1243fc45..f1e40e47 100644
--- a/projects/contrasting_trends_in_snow_loads/gorman_figures/figure  3/figure3_daily snowfall fraction.py	
+++ b/projects/contrasting_trends_in_snow_loads/gorman_figures/daily_snowfall_fraction.py
@@ -8,9 +8,10 @@ from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranR
 Altitudes_groups = [[300, 600, 900], [1200, 1500, 1800], [2100, 2400, 2700], [3000, 3300, 3600]]
 
 
-def compute_smoother_snowfall_fraction(altitudes, year_min, year_max, lim, massif_names=None):
-    all_time_series = np.concatenate(
-        [get_time_series(altitude, year_min, year_max, massif_names) for altitude in altitudes], axis=1)
+def compute_smoother_snowfall_fraction(altitudes, year_min, year_max, lim, massif_names=None, all_time_series=None):
+    if all_time_series is None:
+        all_time_series = np.concatenate(
+            [get_time_series(altitude, year_min, year_max, massif_names) for altitude in altitudes], axis=1)
     temperature_array, snowfall_array, rainfall_array = all_time_series
     # nb_bins_for_one_celsius = 4
     nb_bins_for_one_celsius = 4
@@ -25,10 +26,14 @@ def compute_smoother_snowfall_fraction(altitudes, year_min, year_max, lim, massi
     return np.array(snowfall_fractions), center_bins
 
 
-def daily_snowfall_fraction(ax, altitudes, year_min=1959, year_max=2019, massif_names=None, sigma=1.0):
+def compute_daily_snowfall_fraction(ax=None, altitudes=None, year_min=1959, year_max=2019, massif_names=None, sigma=1.0, plot=True, all_time_series=None):
+    if plot:
+        assert ax is not None
+        assert altitudes is not None
+
     lim = 6
     snowfall_fractions, center_bins = compute_smoother_snowfall_fraction(altitudes, year_min, year_max, lim=lim,
-                                                                         massif_names=massif_names)
+                                                                         massif_names=massif_names, all_time_series=all_time_series)
 
     # Smooth the data afterwards
     snowfall_fractions = 100 * gaussian_filter1d(snowfall_fractions, sigma=sigma)
@@ -39,15 +44,17 @@ def daily_snowfall_fraction(ax, altitudes, year_min=1959, year_max=2019, massif_
     h = np.exp(0.06 * center_bins_interpolation) * snowfall_fractions_interpolated
     temperature_optimal = center_bins_interpolation[np.argmax(h)]
 
+    if plot:
+        # Plot results
+        label = '{}-{} at {}'.format(year_min, year_max, ' & '.join(['{} m'.format(a) for a in altitudes]))
+        ax.set_xlim([-lim, lim])
+        p = ax.plot(center_bins, snowfall_fractions, label=label, linewidth=5)
+        color = p[0].get_color()
+        ax.plot([temperature_optimal], [0], color=color, marker='x', markersize=10)
+        ax.set_ylabel('Snowfall fraction (%)')
+        end_plot(ax, sigma)
 
-    # Plot results
-    label = '{}-{} at {}'.format(year_min, year_max, ' & '.join(['{} m'.format(a) for a in altitudes]))
-    ax.set_xlim([-lim, lim])
-    p = ax.plot(center_bins, snowfall_fractions, label=label, linewidth=5)
-    color = p[0].get_color()
-    ax.plot([temperature_optimal], [0], color=color, marker='x', markersize=10)
-    ax.set_ylabel('Snowfall fraction (%)')
-    end_plot(ax, sigma)
+    return snowfall_fractions_interpolated, center_bins_interpolation, temperature_optimal
 
 
 def snowfall_fraction_difference_between_periods(ax, altitudes, year_min=1959, year_middle=1989, year_max=2019):
@@ -101,7 +108,7 @@ def daily_snowfall_fraction_wrt_altitude(fast=True):
     massif_names = None
     # massif_names = ['Vercors']
     for altitudes in groups:
-        daily_snowfall_fraction(ax, altitudes, massif_names=massif_names)
+        compute_daily_snowfall_fraction(ax, altitudes, massif_names=massif_names)
     plt.show()
 
 
@@ -116,7 +123,7 @@ def daily_snowfall_fraction_wrt_time():
     ax = plt.gca()
     for altitudes in Altitudes_groups:
         for year_min, year_max in [(1959, 1989), (1990, 2019)]:
-            daily_snowfall_fraction(ax, altitudes, year_min, year_max)
+            compute_daily_snowfall_fraction(ax, altitudes, year_min, year_max)
     plt.show()
 
 
diff --git a/projects/contrasting_trends_in_snow_loads/gorman_figures/temperature_of_snowfall_maxima.py b/projects/contrasting_trends_in_snow_loads/gorman_figures/temperature_of_snowfall_maxima.py
new file mode 100644
index 00000000..a47ec2ee
--- /dev/null
+++ b/projects/contrasting_trends_in_snow_loads/gorman_figures/temperature_of_snowfall_maxima.py
@@ -0,0 +1,69 @@
+import matplotlib as mpl
+mpl.rcParams['text.usetex'] = True
+mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}']
+
+from extreme_data.meteo_france_data.scm_models_data.utils import SeasonForTheMaxima, season_to_str
+
+from collections import OrderedDict
+
+import matplotlib.pyplot as plt
+import numpy as np
+
+from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall1Day, SafranTemperature, \
+    SafranPrecipitation1Day
+from projects.contrasting_trends_in_snow_loads.gorman_figures.daily_snowfall_fraction import \
+    compute_daily_snowfall_fraction
+
+
+def distribution_temperature_of_maxima_of_snowfall(altitudes, temperature_at_maxima=True):
+    season = SeasonForTheMaxima.annual if temperature_at_maxima else SeasonForTheMaxima.winter_extended
+    # Load the temperature corresponding to the maxima of snowfall
+    altitude_to_maxima_temperature = OrderedDict()
+    altitude_to_optimal_temperature = OrderedDict()
+    for altitude in altitudes:
+        print(altitude)
+        snowfall_study = SafranSnowfall1Day(altitude=altitude, season=season)
+        temperature_study = SafranTemperature(altitude=altitude, season=season)
+        precipitation_study = SafranPrecipitation1Day(altitude=altitude, season=season)
+        # Compute optimal temperature
+        all_time_series = [temperature_study.all_daily_series, snowfall_study.all_daily_series,
+                           precipitation_study.all_daily_series]
+        *_, optimal_temperature = compute_daily_snowfall_fraction(plot=False, all_time_series=all_time_series)
+        altitude_to_optimal_temperature[altitude] = optimal_temperature
+        # Compute temperature corresponding to maxima
+        maxima_temperatures = []
+        for year in snowfall_study.ordered_years[:2]:
+            a = temperature_study.year_to_daily_time_serie_array[year]
+            if temperature_at_maxima:
+                annual_maxima_index = snowfall_study.year_to_annual_maxima_tuple_indices_for_daily_time_series[year]
+                temp = [a[tuple_idx] for tuple_idx in annual_maxima_index]
+            else:
+                temp = a.flatten()
+            maxima_temperatures.append(temp)
+        altitude_to_maxima_temperature[altitude] = np.concatenate(maxima_temperatures)
+
+    ax = plt.gca()
+    # Plot the optimal temperature
+    ax.plot(altitudes, [altitude_to_optimal_temperature[a] for a in altitudes], marker='o', linestyle='--', label='Optimal temperature for snowfall')
+
+    # Plot the box plot
+    width = 150
+    ax.boxplot([altitude_to_maxima_temperature[a] for a in altitudes], positions=altitudes, widths=width)
+    ax.set_xlim([min(altitudes) - width, max(altitudes) + width])
+    suffix = 'at maxima of snowfall' if temperature_at_maxima else ''
+    ylabel = 'Daily {} temperature {} ({})'.format(season_to_str(season), suffix, temperature_study.variable_class.UNIT)
+    print(ylabel)
+    ax.set_ylabel(ylabel)
+    ax.set_xlabel('Altitude (m)')
+    ax.legend()
+    ax.grid()
+    ax.set_ylim([-8, 5])
+
+    plt.show()
+
+
+if __name__ == '__main__':
+    # altitudes = [900, 1200]
+    altitudes = [900, 1200, 1500, 1800, 2100, 2400, 2700, 3000]
+    distribution_temperature_of_maxima_of_snowfall(altitudes=altitudes,
+                                                   temperature_at_maxima=False)
diff --git a/projects/contrasting_trends_in_snow_loads/temperature_of_snowfall_maxima.py b/projects/contrasting_trends_in_snow_loads/temperature_of_snowfall_maxima.py
deleted file mode 100644
index 6de908ab..00000000
--- a/projects/contrasting_trends_in_snow_loads/temperature_of_snowfall_maxima.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from extreme_data.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall1Day, SafranTemperature
-import numpy as np
-import matplotlib.pyplot as plt
-
-
-def distribution_temperature_of_maxima_of_snowfall(altitudes):
-    # Load the temperature corresponding to the maxima of snowfall
-    altitude_to_maxima_temperature = {}
-    for altitude in altitudes:
-        print(altitude)
-        snowfall_study = SafranSnowfall1Day(altitude=altitude)
-        temperature_study = SafranTemperature(altitude=altitude)
-        # temperature_study = SafranTemperature(altitude=altitude)
-        maxima_temperatures = []
-        for year in snowfall_study.ordered_years[:2]:
-            annual_maxima_index = snowfall_study.year_to_annual_maxima_tuple_indices_for_daily_time_series[year]
-            a = temperature_study.year_to_daily_time_serie_array[year]
-            temp = [a[tuple_idx] for tuple_idx in annual_maxima_index]
-            maxima_temperatures.append(temp)
-        altitude_to_maxima_temperature[altitude] = np.concatenate(maxima_temperatures)
-
-    # Plot the box plot
-    ax = plt.gca()
-    width = 150
-    ax.boxplot(altitude_to_maxima_temperature.values(), positions=altitudes, widths=width)
-    ax.set_xlim([min(altitudes) - width, max(altitudes) + width])
-    ax.set_ylabel('Temperature for maxima of snowfall ({})'.format(temperature_study.variable_class.UNIT))
-    ax.set_xlabel('Altitude (m)')
-    ax.grid()
-
-    plt.show()
-
-
-if __name__ == '__main__':
-    distribution_temperature_of_maxima_of_snowfall(altitudes=[900, 1200, 1500, 1800, 2100, 2400, 2700, 3000])
-- 
GitLab