wolfhece 1.8.7__py3-none-any.whl → 1.8.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
wolfhece/GraphNotebook.py CHANGED
@@ -5,6 +5,8 @@ import wx.lib.agw.aui as aui
5
5
  from shapely.geometry import LineString,Point
6
6
  from matplotlib import figure as mplfig
7
7
  import matplotlib.pyplot as plt
8
+ from matplotlib.axes import Axes
9
+ from matplotlib.figure import Figure
8
10
  from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas, NavigationToolbar2WxAgg as NavigationToolbar
9
11
  import logging
10
12
 
@@ -54,7 +56,7 @@ class PlotPanel(wx.Panel):
54
56
 
55
57
  self.SetSizer(self.sizer) #application du sizer
56
58
 
57
- def add_ax(self, ax3d=False):
59
+ def add_ax(self, ax3d=False) -> Axes:
58
60
  if ax3d:
59
61
  if self.myax is None:
60
62
  self.myax = self.figure.add_subplot(projection='3d')
@@ -63,7 +65,7 @@ class PlotPanel(wx.Panel):
63
65
  self.myax = self.figure.add_subplot()
64
66
  return self.myax
65
67
 
66
- def get_fig_ax(self, ax3d=False):
68
+ def get_fig_ax(self, ax3d=False) -> tuple[Figure, Axes]:
67
69
 
68
70
  if self.myax is None:
69
71
  self.myax = self.add_ax(ax3d)
@@ -653,7 +655,7 @@ class PlotNotebook(wx.Panel):
653
655
  except:
654
656
  pass
655
657
 
656
- def add(self, name="plot",which=""):
658
+ def add(self, name="plot",which="") -> PlotPanel:
657
659
  """
658
660
  Ajout d'un onglet au notebook
659
661
  L'onglet contient une Figure Matplotlib
wolfhece/PyDraw.py CHANGED
@@ -3091,6 +3091,13 @@ class WolfMapViewer(wx.Frame):
3091
3091
 
3092
3092
  def export_results_as(self,which='geotiff'):
3093
3093
 
3094
+ """
3095
+ Export des résultats WOLF2D vers le format GeoTiff
3096
+ On attend que les matrices ".hbin" aient été chargées dans l'interface
3097
+
3098
+ TODO : Modifier la routine pour prendre les classe de résultats 2D
3099
+ """
3100
+
3094
3101
  dlg = wx.DirDialog(self,_('Choose output directory'),style = wx.DD_DIR_MUST_EXIST)
3095
3102
  ret=dlg.ShowModal()
3096
3103
 
@@ -3107,14 +3114,14 @@ class WolfMapViewer(wx.Frame):
3107
3114
  for curarray in self.myarrays:
3108
3115
  if curarray.plotted:
3109
3116
 
3110
- fn = curarray.filename[:-4]
3111
- top = WolfArray(fn+'topini_fine')
3117
+ fn = os.path.splitext(curarray.filename)[0] #curarray.filename[:-4]
3118
+ top = WolfArray(fn+'.topini_fine')
3112
3119
  top.array.mask = curarray.array.mask
3113
3120
  top.array.data[np.where(top.array.mask)] = 0.
3114
- qx = WolfArray(fn+'qxbin')
3121
+ qx = WolfArray(fn+'.qxbin')
3115
3122
  qx.array.mask = curarray.array.mask
3116
3123
  qx.array.data[np.where(qx.array.mask)] = 0.
3117
- qy = WolfArray(fn+'qybin')
3124
+ qy = WolfArray(fn+'.qybin')
3118
3125
  qy.array.mask = curarray.array.mask
3119
3126
  qy.array.data[np.where(qy.array.mask)] = 0.
3120
3127
 
@@ -3122,7 +3129,7 @@ class WolfMapViewer(wx.Frame):
3122
3129
  vnorm=qnorm/curarray
3123
3130
  froude=vnorm/(curarray*9.81)**.5
3124
3131
 
3125
- frott = WolfArray(fn+'frot')
3132
+ frott = WolfArray(fn+'.frot')
3126
3133
 
3127
3134
  def compute_critdiam(h:WolfArray,qnorm:WolfArray,n:WolfArray):
3128
3135
 
@@ -3138,7 +3145,7 @@ class WolfMapViewer(wx.Frame):
3138
3145
 
3139
3146
  return diamcrit_shields,diamcrit_izbach
3140
3147
 
3141
- shields,izbach = compute_critdiam(curarray,qx,qy,frott)
3148
+ shields,izbach = compute_critdiam(curarray,qnorm,frott)
3142
3149
 
3143
3150
  myarrays=[top,curarray,qx,qy,vnorm,froude,shields,izbach]
3144
3151
  mynames=['Z [mDNG]',
wolfhece/PyVertex.py CHANGED
@@ -14,6 +14,7 @@ from os.path import exists
14
14
  import wx
15
15
  import re
16
16
  import logging
17
+ from scipy.spatial import KDTree
17
18
 
18
19
  from .PyParams import Wolf_Param
19
20
  from .PyTranslate import _
@@ -370,7 +371,7 @@ class cloud_vertices(Element_To_Draw):
370
371
 
371
372
  Number os values = nb - (2 or 3) depending if Z coordinate exists
372
373
 
373
- Date are stored in Python dictionnary :
374
+ Data are stored in Python dictionnary :
374
375
  - ['vertex'] == XY or XYZ
375
376
  Each value is accessible through its headname as key :
376
377
  - ['headname1'] == value with headname1
@@ -389,6 +390,7 @@ class cloud_vertices(Element_To_Draw):
389
390
  zbounds: tuple
390
391
 
391
392
  myprop: cloudproperties
393
+ mytree : KDTree
392
394
 
393
395
  def __init__(self, fname: str = '', fromxls: str = '', header: bool = False, toload=True, idx: str = '', plotted: bool = True, mapviewer=None, need_for_wx: bool = False) -> None:
394
396
  super().__init__(idx, plotted, mapviewer, need_for_wx)
@@ -410,6 +412,8 @@ class cloud_vertices(Element_To_Draw):
410
412
 
411
413
  self.myprop = cloudproperties(parent=self)
412
414
 
415
+ self.mytree = None
416
+
413
417
  if fname != '':
414
418
  if toload:
415
419
  if fname[-4:].lower()=='.dxf':
@@ -417,7 +421,37 @@ class cloud_vertices(Element_To_Draw):
417
421
  else:
418
422
  self.readfile(fname, header)
419
423
 
424
+ def __getitem__(self, key):
425
+
426
+ return self.myvertices[key]
427
+
428
+ def create_kdtree(self):
429
+ """
430
+ Set a Scipy KDTree structure based on a copy of the vertices
431
+ """
432
+ xyz = self.get_xyz()
433
+ self.mytree = KDTree(xyz)
434
+
435
+ def find_nearest(self, xy:np.ndarray, nb:int =1):
436
+ """
437
+ Find nearest neighbors from Scipy KDTree structure based on a copy of the vertices
438
+
439
+ Retrun :
440
+ - list of distances
441
+ - list of "Wolfvertex"
442
+ - list of elements stored in self.myvertices
443
+ """
444
+ keys = self.myvertices.keys()
445
+ if self.mytree is None:
446
+ self.create_kdtree()
447
+
448
+ dist, ii = self.mytree.query(xy, k=nb)
449
+ return dist, [self.myvertices[keys[curi]]['vertex'] for curi in ii], [self.myvertices[keys[curi]] for curi in ii]
450
+
420
451
  def init_from_nparray(self, array):
452
+ """
453
+ Fill-in from nparray -- shape (n,3)
454
+ """
421
455
  k = 0
422
456
  for curv in array:
423
457
  mv = wolfvertex(curv[0], curv[1], curv[2])
@@ -710,19 +744,31 @@ class cloud_vertices(Element_To_Draw):
710
744
  self.zmin = 1.e300
711
745
  self.zmax = -1.e300
712
746
 
713
- for item in self.myvertices:
714
- curvert = self.myvertices[item]['vertex']
715
-
716
- x = curvert.x
717
- y = curvert.y
718
- z = curvert.z
719
-
720
- self.xmin = min(x, self.xmin)
721
- self.xmax = max(x, self.xmax)
722
- self.ymin = min(y, self.ymin)
723
- self.ymax = max(y, self.ymax)
724
- self.zmin = min(z, self.zmin)
725
- self.zmax = max(z, self.zmax)
747
+ # if no vertice or file not present -> return
748
+ if len(self.myvertices) == 0 :
749
+ return
750
+
751
+ xyz = self.get_xyz()
752
+ self.xmin = np.min(xyz[:,0])
753
+ self.xmax = np.max(xyz[:,0])
754
+ self.ymin = np.min(xyz[:,1])
755
+ self.ymax = np.max(xyz[:,1])
756
+ self.zmin = np.min(xyz[:,2])
757
+ self.zmax = np.max(xyz[:,2])
758
+
759
+ # for item in self.myvertices:
760
+ # curvert = self.myvertices[item]['vertex']
761
+
762
+ # x = curvert.x
763
+ # y = curvert.y
764
+ # z = curvert.z
765
+
766
+ # self.xmin = min(x, self.xmin)
767
+ # self.xmax = max(x, self.xmax)
768
+ # self.ymin = min(y, self.ymin)
769
+ # self.ymax = max(y, self.ymax)
770
+ # self.zmin = min(z, self.zmin)
771
+ # self.zmax = max(z, self.zmax)
726
772
 
727
773
  self.xbounds = (self.xmin, self.xmax)
728
774
  self.ybounds = (self.ymin, self.ymax)
@@ -730,7 +776,7 @@ class cloud_vertices(Element_To_Draw):
730
776
 
731
777
  pass
732
778
 
733
- def get_xyz(self,key='vertex'):
779
+ def get_xyz(self,key='vertex') -> np.ndarray:
734
780
  if self.header:
735
781
  if key=='vertex':
736
782
  xyz = [[curvert['vertex'].x, curvert['vertex'].y, curvert['vertex'].z] for curvert in self.myvertices.values()]
@@ -89,13 +89,18 @@ class Hydro_HSMF():
89
89
  self._plot_Q(ax)
90
90
  plt.show()
91
91
 
92
- def _plot_Q(self, ax:plt.Axes, decal=0, label=None, lw=2):
92
+ def _plot_Q(self, ax:plt.Axes, decal=0, label=None, lw=2, xup_bound=None):
93
93
 
94
94
  ax.step(list(self.temps+decal)+[self.temps[-1]+decal+1],list(self.hydro)+[0.],where='post',label=label,lw=lw)
95
95
  ax.set_xlabel('Temps [h]')
96
96
  ax.set_ylabel('Débit [$m^3s^{-1}$]')
97
- ax.set_xticks(np.arange(0,self.temps_base+1,1))
98
- ax.set_xbound(0,self.temps_base)
97
+
98
+ if xup_bound is None:
99
+ ax.set_xticks(np.arange(0,self.temps_base+1,1))
100
+ ax.set_xbound(0,self.temps_base)
101
+ else:
102
+ ax.set_xticks(np.arange(0,xup_bound+1,1))
103
+ ax.set_xbound(0,xup_bound)
99
104
  ax.grid()
100
105
 
101
106
  def opt_hydro(self, opti_method = 'brent'):
wolfhece/eva/pyseries.py CHANGED
@@ -31,6 +31,7 @@ try:
31
31
  from .hydrogramme_mono import Hydro_HSMF
32
32
  except:
33
33
  import bootstrap
34
+ from joint_models import JointModel
34
35
  from mixture_models import SeasonMixtureModel
35
36
  from hydrogramme_mono import Hydro_HSMF
36
37
 
@@ -346,7 +347,7 @@ class EVA_Serie:
346
347
  """
347
348
  for curindex in self.nodata.values():
348
349
  if len(curindex)>0:
349
- self.data[curindex]=np.nan
350
+ self.data.iloc[curindex]=np.nan
350
351
 
351
352
  def get_date_max(self, year, seasons=None) -> list():
352
353
  """
@@ -387,6 +388,46 @@ class EVA_Serie:
387
388
 
388
389
  return resevents
389
390
 
391
+ def get_nb_maxevents(self, nbevents:int, seasons=None) -> dict[str, pd.DataFrame]:
392
+ """Récupère les nbevents lus grands pics de crue"""
393
+ seasons = sanitize_seasons(seasons)
394
+
395
+ max_nb = {}
396
+
397
+ for curseason in seasons:
398
+ maxima = pd.DataFrame({'date':self.maxima[curseason]['date'].copy(),
399
+ 'value':self.maxima[curseason]['maxval'].copy()})
400
+ maxima.set_index('date')
401
+ maxima.sort_values(['value'], inplace=True)
402
+
403
+ max_nb[curseason] = maxima.iloc[-nbevents:]
404
+
405
+ return max_nb
406
+
407
+ def get_nb_max_hydro(self, nbevents:int, seasons=None) -> dict[str, pd.DataFrame]:
408
+ """Récupère les nbevents plus grands hydrogrammes de crue"""
409
+ seasons = sanitize_seasons(seasons)
410
+
411
+ ret = {}
412
+ for curseason in seasons:
413
+
414
+ if not 'water_year' in self.maxima[curseason].keys():
415
+ self.find_maxima(self.hydrological_year)
416
+ if not 'events' in self.maxima[curseason].keys():
417
+ self.extract_maxevents()
418
+
419
+ dates = self.maxima[curseason]['date']
420
+ water_year = self.maxima[curseason]['water_year']
421
+ curdict = self.maxima[curseason]['events']
422
+
423
+ hydro = pd.DataFrame({'date':water_year,
424
+ 'hydro':[val for val in curdict.values()],
425
+ 'max':[val.max() for val in curdict.values()]})
426
+ hydro.sort_values('max', inplace=True)
427
+ ret[curseason] = hydro.iloc[-nbevents:]
428
+
429
+ return ret
430
+
390
431
  def save_max_events(self, filename, years_bounds:list=None, seasons=None):
391
432
  """
392
433
  Enregistrement des crues maximales dans un fichier CSV
@@ -455,7 +496,13 @@ class EVA_Serie:
455
496
 
456
497
  return start_date, end_date
457
498
 
458
- def _get_max(self, year=None, hydrol=True, season=None, method: typing.Literal['BM', 'POT'] ='BM', threshold=0., r: typing.Union[pd.Timedelta, typing.Any] = "24H"):
499
+ def _get_max(self,
500
+ year=None,
501
+ hydrol=True,
502
+ season=None,
503
+ method: typing.Literal['BM', 'POT'] ='BM',
504
+ threshold=0.,
505
+ r: typing.Union[pd.Timedelta, typing.Any] = "24H"):
459
506
  """
460
507
  Find maxima in specific period
461
508
  """
@@ -466,7 +513,7 @@ class EVA_Serie:
466
513
  if method=='BM':
467
514
  if len(df)>0:
468
515
  idx = df.argmax()
469
- return [df.index[idx], df[idx]]
516
+ return [df.index[idx], df.iloc[idx]]
470
517
  else:
471
518
  return [None, np.nan]
472
519
  elif method =='POT':
@@ -612,7 +659,7 @@ class EVA_Serie:
612
659
  res = stats.gumbel_r.fit(data,method=method)
613
660
  res = dist.fit(data,0.,loc=res[0],scale=res[1],method=method)
614
661
  elif dist is stats.weibull_min :
615
- # la loi de Weibull étant un cas particulier de la GEV, on initialise les paramétres sur base du fit de la GEV
662
+ # la loi de Weibull étant un cas particulier de la GEV
616
663
  res = stats.gumbel_r.fit(data,method=method)
617
664
  res = dist.fit(data,0.,loc=res[0],scale=res[1],method=method)
618
665
  res = dist.fit(data,1.,loc=res[0],scale=res[1],method=method)
@@ -1123,16 +1170,101 @@ class EVA_Serie:
1123
1170
  curdict['Weibull'] = np.asarray([weibull(i+1,nb) for i in range(nb)])
1124
1171
  curdict['Filliben'] = np.asarray([filliben(i+1,nb) for i in range(nb)])
1125
1172
 
1126
- def get_median_event(self, seasons = None)-> dict[str, pd.DataFrame]:
1173
+ def compute_median_event(self, seasons = None, before:int = 1, after:int = 2):
1174
+ """
1175
+ Evaluation de la crue mediane
1176
+ Stockage dans "self.maxima[curseason]['median_event']"
1177
+ """
1178
+ seasons = sanitize_seasons(seasons)
1179
+
1180
+ nbmax=0
1181
+ for curseason in seasons:
1182
+
1183
+ if not 'events' in self.maxima[curseason].keys():
1184
+ self.extract_maxevents(before,after)
1185
+ elif (self.maxima[curseason]['before'] != before) or (self.maxima[curseason]['after'] != after):
1186
+ self.extract_maxevents(before,after)
1187
+
1188
+ curdict = self.maxima[curseason]['events']
1189
+ dates = self.maxima[curseason]['date']
1190
+
1191
+ all_adims = {}
1192
+ for idx in np.arange((before+after)*24+1, dtype=np.int16):
1193
+ all_adims[idx]=[]
1194
+
1195
+ for idx,(key,curevent) in enumerate(curdict.items()):
1196
+ nb = len(curevent)
1197
+ nbmax = max(nb,nbmax)
1198
+
1199
+ mymax = np.max(curevent)
1200
+ values = curevent.copy()/mymax
1201
+
1202
+ if nb != (before+after)*24+1:
1203
+ x = np.zeros(nb)
1204
+ for curidx, curdelta in enumerate(values.index):
1205
+ curhour = int(((curdelta-dates[idx]).days *24)+((curdelta-dates[idx]).seconds)/3600) + before*24
1206
+ x[curidx] = curhour
1207
+ all_adims[curhour].append(values[curidx])
1208
+ else:
1209
+ x = np.arange((before+after)*24+1, dtype=np.int16)
1210
+ for curidx, curq in enumerate(values):
1211
+ all_adims[curidx].append(curq)
1212
+
1213
+ time= np.arange((before+after)*24+1, dtype=np.int16)
1214
+ crue_mediane = [np.median(curval) for curval in all_adims.values()]
1215
+ self.maxima[curseason]['median_event'] = pd.DataFrame({'time [hour]':time, 'Discharge[m3s-1]':crue_mediane})
1216
+
1217
+ def get_median_event(self, seasons = None, before=1, after=2)-> dict[str, pd.DataFrame]:
1218
+ """
1219
+ Get median hydrograph
1220
+ """
1127
1221
 
1128
1222
  seasons = sanitize_seasons(seasons)
1129
1223
 
1130
1224
  retdict = {}
1131
1225
  for cur in seasons:
1226
+ # if not 'median_event' in self.maxima[cur].keys():
1227
+ self.compute_median_event(seasons, before, after)
1228
+
1132
1229
  retdict[cur] = self.maxima[cur]['median_event']
1133
1230
 
1134
1231
  return retdict
1135
1232
 
1233
+ def plot_median_event(self,
1234
+ scale:float,
1235
+ seasons = None,
1236
+ before=1,
1237
+ after=2,
1238
+ fig:Figure=None,
1239
+ ax:Axes=None,
1240
+ color:str='red',
1241
+ alpha=1.) -> tuple([Figure,Axes]):
1242
+ """
1243
+ Plot median hydrograph scale by constant
1244
+ """
1245
+
1246
+ seasons = sanitize_seasons(seasons)
1247
+
1248
+ if fig is None and ax is None:
1249
+ fig,ax = plt.subplots(len(seasons),1)
1250
+
1251
+ qmedian = self.get_median_event(seasons, before, after)
1252
+
1253
+ k=0
1254
+ for curseason in seasons:
1255
+ if len(seasons)==1:
1256
+ curax=ax
1257
+ else:
1258
+ curax=ax[k]
1259
+
1260
+ x = qmedian[curseason]['time [hour]']
1261
+ crue_mediane = qmedian[curseason]['Discharge[m3s-1]'].copy() * scale
1262
+
1263
+ curax.step(x,crue_mediane,where='post', c=color, alpha=alpha, lw=2, label = "Median")
1264
+
1265
+ k+=1
1266
+
1267
+
1136
1268
  def plot_classified_flowrate_curve(self, fig:Figure=None, ax:Axes=None, label='', textvalues=True, show=False) -> tuple([Figure,Axes]):
1137
1269
 
1138
1270
  if ax is None:
@@ -1435,6 +1567,10 @@ class EVA_Serie:
1435
1567
  else:
1436
1568
  for curseason in seasons:
1437
1569
  if curseason != 'mixture' and curseason != 'joint':
1570
+
1571
+ if len(self.maxima.keys())==0:
1572
+ self.find_maxima()
1573
+
1438
1574
  if not 'sorted_maxval' in self.maxima[curseason].keys():
1439
1575
  self.sort_maxima(curseason)
1440
1576
  self.set_empfreq(curseason)
@@ -1475,6 +1611,8 @@ class EVA_Serie:
1475
1611
  if fig is None and ax is None:
1476
1612
  fig,ax = plt.subplots(len(seasons),1)
1477
1613
 
1614
+ self.compute_median_event(seasons, before, after)
1615
+
1478
1616
  nbmax=0
1479
1617
  k=0
1480
1618
  for curseason in seasons:
@@ -1498,12 +1636,12 @@ class EVA_Serie:
1498
1636
  locmax = list(locmax[-nbevents:])
1499
1637
 
1500
1638
  all_adims = {}
1501
- for idx in np.arange((before+after)*24+1, dtype=np.int16): #np.arange(-before*24,after*24+1, dtype=np.int16):
1639
+ for idx in np.arange((before+after)*24+1, dtype=np.int16):
1502
1640
  all_adims[idx]=[]
1503
1641
 
1504
1642
  for idx,(key,curevent) in enumerate(curdict.items()):
1505
- nb=len(curevent)
1506
- nbmax=max(nb,nbmax)
1643
+ nb = len(curevent)
1644
+ nbmax = max(nb,nbmax)
1507
1645
 
1508
1646
  mymax = np.max(curevent)
1509
1647
  if adim:
@@ -1518,7 +1656,7 @@ class EVA_Serie:
1518
1656
  x[curidx] = curhour
1519
1657
  all_adims[curhour].append(values[curidx])
1520
1658
  else:
1521
- x = np.arange((before+after)*24+1, dtype=np.int16) #np.arange(-before*24,after*24+1, dtype=np.int16)
1659
+ x = np.arange((before+after)*24+1, dtype=np.int16)
1522
1660
  for curidx, curq in enumerate(values):
1523
1661
  all_adims[curidx].append(curq)
1524
1662
 
@@ -1526,21 +1664,24 @@ class EVA_Serie:
1526
1664
  curax.step(x,values,where='post',alpha=alpha,c=colors[k], label = dates[idx].strftime("%m/%Y"))
1527
1665
  elif mymax in locmax:
1528
1666
  curax.step(x,values,where='post',alpha=alpha,c=colors[k], label = dates[idx].strftime("%m/%Y"))
1667
+ print(dates[idx].strftime("%m/%Y"), mymax)
1529
1668
 
1530
1669
  if adim:
1531
- x = np.arange((before+after)*24+1, dtype=np.int16) #np.arange(-before*24,after*24+1, dtype=np.int16)
1532
- crue_mediane = [np.median(curval) for curval in all_adims.values()]
1533
- curax.step(x,crue_mediane,where='post',alpha=1., c=colors[k], lw=2, label = "median")
1534
-
1535
- self.maxima[curseason]['median_event'] = pd.DataFrame({'time [hour]':x, 'Discharge[m3s-1]':crue_mediane})
1670
+ x = self.maxima[curseason]['median_event']['time [hour]']
1671
+ crue_mediane = self.maxima[curseason]['median_event']['Discharge[m3s-1]']
1672
+ curax.step(x,crue_mediane,where='post',alpha=1., c=colors[k], lw=2, label = "Median")
1536
1673
 
1537
1674
  curax.set_xticks(np.arange(0, (before+after)*24+1, 6, dtype=np.int16))
1538
1675
  curax.set_xticklabels(np.arange(0, (before+after)*24+1, 6, dtype=np.int16))
1539
1676
  curax.grid(True)
1540
- # ax.legend()
1677
+
1541
1678
  curax.set_title('Maxima events - duration : {} - {}'.format(self.duration,curseason))
1542
1679
  curax.set_xlabel('Time [hour]')
1543
- curax.set_ylabel('Discharge / DisMax [-]')
1680
+
1681
+ if adim:
1682
+ curax.set_ylabel('Discharge / DisMax [-]')
1683
+ else:
1684
+ curax.set_ylabel('Discharge [$m^3s^{-1}$]')
1544
1685
  curax.set_xbound(0,(before+after)*24+1)
1545
1686
  k+=1
1546
1687
 
@@ -1610,7 +1751,7 @@ class EVA_Serie:
1610
1751
 
1611
1752
  x = np.arange((before+after)*24+1, dtype=np.int16)
1612
1753
  crue_mediane = [np.median(curval) for curval in all_adims.values()]
1613
- curax.step(x,crue_mediane,where='post',alpha=1., c=colors[k], lw=2, label = curseason)
1754
+ curax.step(x,crue_mediane,where='post',alpha=1., c=colors[k], lw=2, label = 'MedianQ {}'.format(curseason))
1614
1755
 
1615
1756
  self.maxima[curseason]['median_event'] = pd.DataFrame({'time [hour]':x, 'Discharge[m3s-1]':crue_mediane})
1616
1757
 
@@ -1916,11 +2057,14 @@ class EVA_Serie:
1916
2057
  aic = np.asarray([curdictm[curlaw]['aic'] for curlaw in curdictm.keys()])
1917
2058
  aicc = np.asarray([curdictm[curlaw]['aicc'] for curlaw in curdictm.keys()])
1918
2059
  bic = np.asarray([curdictm[curlaw]['bic'] for curlaw in curdictm.keys()])
1919
- rss = np.asarray([curdictm[curlaw]['rss'] for curlaw in curdictm.keys()])
2060
+ rss = np.asarray([curdictm[curlaw]['rss'] for curlaw in curdictm.keys()] )
1920
2061
 
1921
2062
  labels = np.asarray(list(curdictm.keys()))
1922
2063
 
1923
- if (nb_laws>len(aicc)) or (nb_laws is None):
2064
+ if nb_laws is None:
2065
+ nb_laws=len(aicc)
2066
+
2067
+ if nb_laws>len(aicc):
1924
2068
  nb_laws=len(aicc)
1925
2069
 
1926
2070
  if sort=='RSS':
@@ -1978,7 +2122,7 @@ class EVA_Serie:
1978
2122
  if show:
1979
2123
  plt.show()
1980
2124
 
1981
- return fig, ax, list(labels[index_sort])
2125
+ return fig, ax, list(labels[index_sort][:nb_laws])
1982
2126
 
1983
2127
  def summary_max(self, seasons=None):
1984
2128
 
@@ -2232,7 +2376,7 @@ class EVA_Series:
2232
2376
  threshold: float=0.,
2233
2377
  r: typing.Union[pd.Timedelta, typing.Any] = "24H",
2234
2378
  verbose=True,
2235
- show=False) -> list:
2379
+ show=False) -> dict[str, tuple]:
2236
2380
  """
2237
2381
  Extreme Value Analysis
2238
2382
 
@@ -2410,8 +2554,14 @@ class EVA_Series:
2410
2554
  for curT in return_period:
2411
2555
  dict[curT] = self.get_one_MFSH(rising_time, curT, deltat)
2412
2556
 
2413
- def plot_msfh(self, label, return_period= [2, 5, 10, 25, 50, 100, 200, 500, 1000],
2414
- ref_season='annual', ylim=None, show=False) -> tuple([Figure, Axes, Axes]):
2557
+ def plot_msfh(self,
2558
+ label,
2559
+ return_period= [2, 5, 10, 25, 50, 100, 200, 500, 1000],
2560
+ ref_season='annual',
2561
+ ylim=None,
2562
+ before = 1,
2563
+ after = 3,
2564
+ show=False) -> tuple([Figure, Axes, Axes]):
2415
2565
  """
2416
2566
  ################
2417
2567
  ## GRAPHIQUES ##
@@ -2422,7 +2572,7 @@ class EVA_Series:
2422
2572
  raise Warning('No hydrogram to plot -- retry')
2423
2573
 
2424
2574
  ref_serie = self.all_series[1]
2425
- fig, ax = ref_serie.plot_maxevents(ref_season, 1, 4, alpha=.15)
2575
+ fig, ax = ref_serie.plot_maxevents(ref_season, before, after, alpha=.15)
2426
2576
 
2427
2577
  ax2 = ax.twinx()
2428
2578
 
@@ -2430,7 +2580,7 @@ class EVA_Series:
2430
2580
  curhydro:Hydro_HSMF
2431
2581
  curhydro=self.MFSH[label][curT]
2432
2582
 
2433
- curhydro._plot_Q(ax2, 24 - curhydro.temps_montee, label=str(curT), lw=3)
2583
+ curhydro._plot_Q(ax2, before*24 - curhydro.temps_montee, label=str(curT), lw=3, xup_bound=(before+after)*24)
2434
2584
 
2435
2585
  ax.legend().set_visible(False)
2436
2586
  ax2.legend()
@@ -2443,6 +2593,41 @@ class EVA_Series:
2443
2593
 
2444
2594
  return fig,ax,ax2
2445
2595
 
2596
+ def plot_msfh_mainplot(self,
2597
+ label,
2598
+ return_period= [2, 5, 10, 25, 50, 100, 200, 500, 1000],
2599
+ ref_season='annual',
2600
+ ylim=None,
2601
+ before = 1,
2602
+ after=2,
2603
+ show=False) -> tuple([Figure, Axes]):
2604
+ """
2605
+ ################
2606
+ ## GRAPHIQUES ##
2607
+ ################
2608
+ """
2609
+
2610
+ if not label in self.MFSH.keys():
2611
+ raise Warning('No hydrogram to plot -- retry')
2612
+
2613
+ fig,ax = plt.subplots(1,1)
2614
+
2615
+ for curT in return_period:
2616
+ curhydro:Hydro_HSMF
2617
+ curhydro=self.MFSH[label][curT]
2618
+
2619
+ curhydro._plot_Q(ax, before*24 - curhydro.temps_montee, label=str(curT), lw=3, xup_bound=(before+after)*24)
2620
+
2621
+ ax.legend()
2622
+
2623
+ if ylim is not None:
2624
+ ax.set_ylim(ylim)
2625
+
2626
+ if show:
2627
+ plt.show()
2628
+
2629
+ return fig,ax
2630
+
2446
2631
  def save_max_event(self,
2447
2632
  filename:str,
2448
2633
  years_bounds:list,
File without changes