diff --git a/experiment/meteo_france_SCM_study/abstract_study.py b/experiment/meteo_france_SCM_study/abstract_study.py
index 264d1fbb1a219c17f58b3e851d770a92d1118f1a..7fc67358c735f921e7a77bdd0bf3c6f08686e02a 100644
--- a/experiment/meteo_france_SCM_study/abstract_study.py
+++ b/experiment/meteo_france_SCM_study/abstract_study.py
@@ -34,7 +34,7 @@ class AbstractStudy(object):
 
     @property
     def df_all_snowfall_concatenated(self) -> pd.DataFrame:
-        df_list = [pd.DataFrame(snowfall, columns=self.safran_massif_names) for snowfall in
+        df_list = [pd.DataFrame(time_serie, columns=self.safran_massif_names) for time_serie in
                    self.year_to_daily_time_serie.values()]
         df_concatenated = pd.concat(df_list)
         return df_concatenated
@@ -111,7 +111,6 @@ class AbstractStudy(object):
     """ Visualization methods """
 
     def visualize(self, ax=None, massif_name_to_fill_kwargs=None, show=True, fill=True):
-        print("here")
         if ax is None:
             ax = plt.gca()
         df_massif = pd.read_csv(op.join(self.map_full_path, 'massifsalpes.csv'))
@@ -135,6 +134,14 @@ class AbstractStudy(object):
 
     """ Some properties """
 
+    @property
+    def title(self):
+        return "{} at altitude {}m".format(self.variable_name, self.altitude)
+
+    @property
+    def variable_name(self):
+        return self.variable_class.NAME
+
     @property
     def relative_path(self) -> str:
         return r'local/spatio_temporal_datasets'
diff --git a/experiment/meteo_france_SCM_study/abstract_variable.py b/experiment/meteo_france_SCM_study/abstract_variable.py
index acc653c78c5916291296296cd6af89d0018c03a7..777d7f21f4d9c623e275eb2cfaf3146ba669161d 100644
--- a/experiment/meteo_france_SCM_study/abstract_variable.py
+++ b/experiment/meteo_france_SCM_study/abstract_variable.py
@@ -2,6 +2,8 @@
 
 class AbstractVariable(object):
 
+    NAME = ''
+
     def __init__(self, dataset):
         self.dataset = dataset
 
diff --git a/experiment/meteo_france_SCM_study/crocus/crocus_variables.py b/experiment/meteo_france_SCM_study/crocus/crocus_variables.py
index 1825a43791648c6049cd6e711d0901b238dd4a11..5ba0707ef3925da01d631a1352dd44621c425ff5 100644
--- a/experiment/meteo_france_SCM_study/crocus/crocus_variables.py
+++ b/experiment/meteo_france_SCM_study/crocus/crocus_variables.py
@@ -16,12 +16,14 @@ class CrocusVariable(AbstractVariable):
 
 
 class CrocusSweVariable(CrocusVariable):
+    NAME = 'Snow Water Equivalent'
 
     def __init__(self, dataset):
         super().__init__(dataset, 'SNOWSWE')
 
 
 class CrocusDepthVariable(CrocusVariable):
+    NAME = 'Snow Depth'
 
     def __init__(self, dataset):
         super().__init__(dataset, "SNOWDEPTH")
diff --git a/experiment/meteo_france_SCM_study/main_visualize.py b/experiment/meteo_france_SCM_study/main_visualize.py
index dc249ce215e4791b7f5c5a48a67767915c092bb2..d7203624bd618ca1a4919a5b496cee67879b5ff0 100644
--- a/experiment/meteo_france_SCM_study/main_visualize.py
+++ b/experiment/meteo_france_SCM_study/main_visualize.py
@@ -9,7 +9,7 @@ from experiment.meteo_france_SCM_study.safran.safran_visualizer import StudyVisu
 def load_all_studies(study_class, only_first_one=False):
     all_studies = []
     is_safran_study = study_class == Safran
-    nb_days = [1, 5] if is_safran_study else [1]
+    nb_days = [3, 1] if is_safran_study else [1]
     for alti, nb_day in product(AbstractStudy.ALTITUDES, nb_days):
         print('alti: {}, nb_day: {}'.format(alti, nb_day))
         study = Safran(alti, nb_day) if is_safran_study else study_class(alti)
@@ -20,9 +20,10 @@ def load_all_studies(study_class, only_first_one=False):
 
 
 if __name__ == '__main__':
-    for study_class in [Safran, CrocusSwe, CrocusDepth][:]:
+    for study_class in [Safran, CrocusSwe, CrocusDepth][1:2]:
         for study in load_all_studies(study_class, only_first_one=True):
             study_visualizer = StudyVisualizer(study)
-            # safran_visualizer.visualize_independent_margin_fits(threshold=[None, 20, 40, 60][0])
-            study_visualizer.visualize_smooth_margin_fit()
-            # safran_visualizer.visualize_full_fit()
+            # study_visualizer.visualize_independent_margin_fits(threshold=[None, 20, 40, 60][0])
+            # study_visualizer.visualize_smooth_margin_fit()
+            study_visualizer.visualize_all_kde_graphs()
+            # study_visualizer.visualize_full_fit()
diff --git a/experiment/meteo_france_SCM_study/safran/safran.py b/experiment/meteo_france_SCM_study/safran/safran.py
index 81b463445c4370b667f7e2aab1c72f725d0a8420..b485bafd1d5eae36a9ce44ab9e0940a8f19175c8 100644
--- a/experiment/meteo_france_SCM_study/safran/safran.py
+++ b/experiment/meteo_france_SCM_study/safran/safran.py
@@ -12,3 +12,8 @@ class Safran(AbstractStudy):
 
     def instantiate_variable_object(self, dataset) -> AbstractVariable:
         return self.variable_class(dataset, self.nb_days_of_snowfall)
+
+    @property
+    def variable_name(self):
+        return super().variable_name() + 'cumulated over {} days'.format(self.nb_days_of_snowfall)
+
diff --git a/experiment/meteo_france_SCM_study/safran/safran_snowfall_variable.py b/experiment/meteo_france_SCM_study/safran/safran_snowfall_variable.py
index 04b25737727e049d82fd0900b056260af4a2f47f..491dd3d230db7c386adf35e44d4bba1b6fac72a0 100644
--- a/experiment/meteo_france_SCM_study/safran/safran_snowfall_variable.py
+++ b/experiment/meteo_france_SCM_study/safran/safran_snowfall_variable.py
@@ -19,6 +19,8 @@ class SafranSnowfallVariable(AbstractVariable):
         (but here the problem might be that the x_i are not idnependent, they are highly dependent one from another)
     """
 
+    NAME = 'Snowfall'
+
     def __init__(self, dataset, nb_consecutive_days_of_snowfall=1):
         super().__init__(dataset)
         self.nb_consecutive_days_of_snowfall = nb_consecutive_days_of_snowfall
@@ -46,3 +48,5 @@ class SafranSnowfallVariable(AbstractVariable):
 
 
 
+
+
diff --git a/experiment/meteo_france_SCM_study/safran/safran_visualizer.py b/experiment/meteo_france_SCM_study/safran/safran_visualizer.py
index 517ea10aae1db6e809b7abf6b0f7ca035a755169..cbc0359481023446180de8dad0f062a988d3efca 100644
--- a/experiment/meteo_france_SCM_study/safran/safran_visualizer.py
+++ b/experiment/meteo_france_SCM_study/safran/safran_visualizer.py
@@ -1,3 +1,6 @@
+import math
+import numpy as np
+
 import matplotlib.pyplot as plt
 import pandas as pd
 
@@ -11,7 +14,6 @@ from extreme_estimator.margin_fits.gev.gev_params import GevParams
 from extreme_estimator.margin_fits.gev.gevmle_fit import GevMleFit
 from extreme_estimator.margin_fits.gpd.gpd_params import GpdParams
 from extreme_estimator.margin_fits.gpd.gpdmle_fit import GpdMleFit
-from experiment.meteo_france_SCM_study.safran.safran import Safran
 from extreme_estimator.margin_fits.plot.create_shifted_cmap import get_color_rbga_shifted
 from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
 
@@ -21,6 +23,7 @@ class StudyVisualizer(object):
     def __init__(self, study: AbstractStudy, show=True):
         self.study = study
         self.show = show
+        self.window_size_for_smoothing = 21
 
     @property
     def observations(self):
@@ -34,6 +37,60 @@ class StudyVisualizer(object):
     def dataset(self):
         return AbstractDataset(self.observations, self.coordinates)
 
+    def visualize_all_kde_graphs(self, show=True):
+        massif_names = self.study.safran_massif_names
+        nb_columns = 5
+        nb_rows = math.ceil(len(massif_names) / nb_columns)
+        fig, axes = plt.subplots(nb_rows, nb_columns)
+        fig.subplots_adjust(hspace=1.0, wspace=1.0)
+        for i, massif_name in enumerate(massif_names):
+            row_id, column_id = i // nb_columns, i % nb_columns
+            ax = axes[row_id, column_id]
+            self.visualize_kde_graph(ax, i, massif_name)
+        title = self.study.title
+        title += '  (mean computed with a sliding window of size {})'.format(self.window_size_for_smoothing)
+        fig.suptitle(title)
+        if show:
+            plt.show()
+
+    def visualize_kde_graph(self, ax, i, massif_name):
+        self.maxima_plot(ax, i)
+        self.mean_plot(ax, i)
+        ax.set_xlabel('year')
+        ax.set_title(massif_name)
+
+    def mean_plot(self, ax, i):
+        # Display the mean graph
+        # Counting the sum of 3-consecutive days of snowfall does not have any physical meaning,
+        # as we are counting twice some days
+        color_mean = 'g'
+        tuples_x_y = [(year, np.mean(data[:, i])) for year, data in self.study.year_to_daily_time_serie.items()]
+        x, y = list(zip(*tuples_x_y))
+        x, y = self.smooth(x, y)
+        ax.plot(x, y, color=color_mean)
+        ax.set_ylabel('mean', color=color_mean)
+
+    def maxima_plot(self, ax, i):
+        # Display the graph of the max on top
+        color_maxima = 'r'
+        tuples_x_y = [(year, annual_maxima[i]) for year, annual_maxima in self.study.year_to_annual_maxima.items()]
+        x, y = list(zip(*tuples_x_y))
+        ax2 = ax.twinx()
+        ax2.plot(x, y, color=color_maxima)
+        ax2.set_ylabel('maxima', color=color_maxima)
+
+    def smooth(self, x, y):
+        # Average on windows of size 2*M+1 (M elements on each side)
+        filter = np.ones(self.window_size_for_smoothing) / self.window_size_for_smoothing
+        y = np.convolve(y, filter, mode='valid')
+        assert self.window_size_for_smoothing % 2 == 1
+        nb_to_delete = int(self.window_size_for_smoothing // 2)
+        x = np.array(x)[nb_to_delete:-nb_to_delete]
+        assert len(x) == len(y)
+        return x, y
+
+
+
     def fit_and_visualize_estimator(self, estimator):
         estimator.fit()
         axes = estimator.margin_function_fitted.visualize(show=False)