diff --git a/GenerateurCruesMaxAnnuelles.py b/GenerateurCruesMaxAnnuelles.py index 8c953795f8f64b0da3be382e545a7b70affc90bc..35f1301bcf711c1effbaba8ec79e2e53b565336c 100644 --- a/GenerateurCruesMaxAnnuelles.py +++ b/GenerateurCruesMaxAnnuelles.py @@ -170,33 +170,26 @@ def T_emp_parametre(n_annees, a , b): return plotting_positions_param -def update_vlines(courbe_en_vlines, x, ymin=None, ymax=None): - # mise à jour de courbes de type vlines - # https://stackoverflow.com/questions/29331401/updating-pyplot-vlines-in-interactive-plot - seg_old = courbe_en_vlines.get_segments() - if ymin is None: - ymin = seg_old[0][0, 1] - if ymax is None: - ymax = seg_old[0][1, 1] - - seg_new = [np.array([[xx, ymin], - [xx, ymax]]) for xx in x] - - courbe_en_vlines.set_segments(seg_new) - def retracer_parametree(echantillon, a, b): - y_max = max(echantillon) + # si switch : au lieu de "updater", on retrace complètement en attendant se pouvoir updater des stems.. + global stemlines_emp, markerline_emp , baseline_emp + if en_periode_de_retour: - T_emp = T_emp_parametre(len(echantillon), a, b) - update_vlines(courbe_estim_T_vlines, T_emp, ymin=0, ymax=y_max) - ax_T.set_title(f"T empirique pour a={a:.2f} et b={b:.2f} ") + x_emp = T_emp_parametre(len(echantillon), a, b) else: - #freq = [ 1 - (1 / T) for T in T_emp] - freq = freq_emp_parametre(len(echantillon), a , b) - update_vlines(courbe_estim_T_vlines, freq, ymin=0, ymax=y_max) - ax_T.set_title(f"fréquence empirique pour a={a:.2f} et b={b:.2f} ") + # freq = [ 1 - (1 / T) for T in T_emp] + x_emp = freq_emp_parametre(len(echantillon), a, b) + + for item in [stemlines_emp, markerline_emp, baseline_emp]: + item.remove() + + markerline_emp, stemlines_emp, baseline_emp = ax_T.stem(x_emp, serie_Gumbel.serie_triee, label=f"T ou f empirique, fonction de a et b", + use_line_collection=True) + + plt.setp(stemlines_emp, color='purple') + plt.setp(markerline_emp, color='cyan', markersize=2, markeredgecolor='blue', markeredgewidth=3) + plt.setp(baseline_emp, visible=False) - #ax.set_xbounds(lower=min(T_emp), upper=max(T_emp)) # on retrace fig_pp.canvas.draw_idle() @@ -206,7 +199,7 @@ def retracer_Gumbel(serie_Gumbel): courbe_Gumbel.set_xdata(SerieGumbel.T_Gumbel_plot) else: #freq = [ 1 - (1 / T) for T in T_emp] - freq = [ 1 - (1/T) for T in SerieGumbel.T_Gumbel_plot] + freq = [1 - (1/T) for T in SerieGumbel.T_Gumbel_plot] courbe_Gumbel.set_xdata(freq) # on retrace @@ -214,12 +207,13 @@ def retracer_Gumbel(serie_Gumbel): def retracer_estim_Gumbel(serie_Gumbel): gr, x0 = AjustementParametresDeGumbel(np.mean(serie_Gumbel), np.std(serie_Gumbel)) + T_estim_Gumbel = [TdeQ_Gumbel(Q, gr, x0) for Q in serie_Gumbel] if en_periode_de_retour: - T_Gumbel = [TdeQ_Gumbel(Q, gr, x0) for Q in serie_Gumbel] - courbe_estim_Gumbel.set_data(T_Gumbel, serie_Gumbel) + + courbe_estim_Gumbel.set_data(T_estim_Gumbel, serie_Gumbel) else: # freq = [ 1 - (1 / T) for T in T_emp] - freq = freq_emp_parametre(len(serie_Gumbel), a, b) + freq = [ 1 - (1 / T) for T in T_estim_Gumbel] courbe_estim_Gumbel.set_data(freq, serie_Gumbel) # on retrace @@ -240,6 +234,59 @@ def update_b(val): b = val # comme on a précisé "global b", changer b dans la fonction = changer b du prog principal retracer_parametree(serie_Gumbel.serie_triee, a, b) +def create_series(event): + # bouton "recréer une série de N obs" activé + + # comme on a précisé "global N_total, echantillon", sa modifications sera propagée jusque dans le prog principal + global N_total, serie_Gumbel, gr_est, x0_est, courbe_estim_Gumbel, stemlines_emp, markerline_emp, baseline_emp + + serie_Gumbel = SerieGumbel(x0=196, gr=102) + serie_Gumbel.ajout_obs(N_serie) + + N_total = N_serie + + print("Première série d'obs : ", serie_Gumbel.serie_chrono) + + ax_chrono.clear() + ax_T.clear() + # LES OBS + derniere_annee = 1 + len(serie_Gumbel.serie_chrono) + ax_chrono.vlines(x=range(1, derniere_annee), ymin=0, ymax=serie_Gumbel.serie_chrono) + ax_chrono.scatter(range(1, derniere_annee), serie_Gumbel.serie_chrono, + c=serie_Gumbel.serie_couleurs, alpha=0.7, + label=f"Q(t) observé sur {N_total} années, ", marker="*", s=60) + + gr_est, x0_est = serie_Gumbel.gr_echantillon, serie_Gumbel.x0_echantillon + + # LA COURBE DE GUMBEL, inchangée (sauf si tracé en fréquence...) + if en_periode_de_retour: + x_Gumbel = SerieGumbel.T_Gumbel_plot + x_emp = T_emp_parametre(N_total, a, b) + x_estimGumbel = [TdeQ_Gumbel(Q, gr_est, x0_est) for Q in serie_Gumbel.serie_triee] + else: + x_Gumbel = [1- (1/T) for T in SerieGumbel.T_Gumbel_plot] + x_emp = [1- (1/T) for T in T_emp_parametre(N_total, a, b)] + x_estimGumbel = [1 - (1 / TdeQ_Gumbel(Q, gr_est, x0_est)) for Q in serie_Gumbel.serie_triee] + + courbe_Gumbel, = ax_T.plot(x_Gumbel, serie_Gumbel.QGumbel_plot, alpha=0.7, color='orangered', + linewidth=5, solid_capstyle='round', + zorder=10, label="Q(T) du bassin versant", marker="None", ls='--', markersize=7) + # courbe_estim_T_stem = markerline, stemlines, baseline (objet retournés par la fonction) + markerline_emp, stemlines_emp, baseline_emp = ax_T.stem(x_emp, serie_Gumbel.serie_triee, label=f"T ou f empirique, fonction de a et b", use_line_collection=True) + + plt.setp(stemlines_emp, color='purple') + plt.setp(markerline_emp, color ='cyan', markersize=5, markeredgecolor ='blue', markeredgewidth = 3) + plt.setp(baseline_emp, visible=False) + + courbe_estim_Gumbel, = ax_T.plot(x_estimGumbel, serie_Gumbel.serie_triee, color='blue', alpha=0.7, + label=" ajustement Gumbel sur obs", + zorder=10, marker="x", markersize=7) + ax_T.legend() + fig_pp.canvas.draw_idle() + + return serie_Gumbel, courbe_Gumbel, gr_est, x0_est, courbe_estim_Gumbel, stemlines_emp, markerline_emp, baseline_emp + + def update_series(event): # bouton "ajouter des obs" activé @@ -249,28 +296,34 @@ def update_series(event): serie_Gumbel.ajout_obs(N_serie) ax_chrono.clear() + derniere_annee = 1 + len(serie_Gumbel.serie_chrono) ax_chrono.set_title(f"Qmax annuels observés sur {N_total} années") - courbe_Gumbel1, = ax_chrono.plot(range(len(serie_Gumbel.serie_chrono)), serie_Gumbel.serie_chrono, ls='--') - courbe_Gumbel = ax_chrono.scatter(range(len(serie_Gumbel.serie_chrono)), serie_Gumbel.serie_chrono, + ax_chrono.vlines(x=range(1, derniere_annee), ymin=0, ymax=serie_Gumbel.serie_chrono, colors=serie_Gumbel.serie_couleurs) #, ls="--') + ax_chrono.scatter(range(1, derniere_annee), serie_Gumbel.serie_chrono, c=serie_Gumbel.serie_couleurs, alpha=0.7, marker="*", s=20) retracer_estim_Gumbel(serie_Gumbel.serie_triee) - fig_pp.canvas.draw_idle() retracer_parametree(serie_Gumbel.serie_triee, a, b) + fig_pp.canvas.draw_idle() def switch_freq(label): global en_periode_de_retour en_periode_de_retour = not en_periode_de_retour + retracer_parametree(serie_Gumbel.serie_triee, a, b) retracer_Gumbel(serie_Gumbel.serie_triee) retracer_estim_Gumbel(serie_Gumbel.serie_triee) if en_periode_de_retour: - ax_T.set_xlim(left=0, right=N_total * 1.1) + ax_T.set_xlim(left=0, right= (N_total + b)/(1 - a) * 1.1) ax_T.set_xlabel("Période de retour, années") + bouton_T2F.label.set_text('Période de retour => fréquence') else: # freq = [ 1 - (1 / T) for T in T_emp] ax_T.set_xlim(left=0, right=1.1) ax_T.set_xlabel("fréquence de non-dépassement") + bouton_T2F.label.set_text('fréquence => Période de retour') + + ax_T.set_ylim(bottom=0, top=max(serie_Gumbel.serie_triee) * 1.1) fig_pp.canvas.draw_idle() @@ -283,59 +336,43 @@ b = b_Tchego # on va constituer une série d' "observations" par ajouts de N_series obs à la fois N_serie = 10 -serie_Gumbel = SerieGumbel(x0=196, gr=102) -serie_Gumbel.ajout_obs(N_serie) - -rangs = echantillon_uniforme(N_serie) +#rangs = echantillon_uniforme(N_serie) -N_total = N_serie en_periode_de_retour = True -print(serie_Gumbel.serie_chrono) - - fig_pp = plt.figure() -gs = gridspec.GridSpec(16, 2) +gs = gridspec.GridSpec(17, 2) ax_chrono = plt.subplot(gs[0:6, :]) -ax_T = plt.subplot(gs[6:12, :]) -ax_slide_a = plt.subplot(gs[15, 0]) -ax_slide_b = plt.subplot(gs[15, 1]) -ax_chb = plt.subplot(gs[14, 0]) -ax_bouton = plt.subplot(gs[14, 1]) +ax_bouton = plt.subplot(gs[7, 0]) +ax_bouton_RAZ = plt.subplot(gs[7, 1]) +ax_T = plt.subplot(gs[8:13, :]) +ax_slide_a = plt.subplot(gs[16, 0]) +ax_slide_b = plt.subplot(gs[16, 1]) +ax_T2f = plt.subplot(gs[15, :]) # ax_chb = fig.add_subplot() -plt.subplots_adjust(wspace=1, hspace=0.5,left=0.1,top=0.85,right=0.9,bottom=0.1) +plt.subplots_adjust(wspace=1, hspace=0.5,left=0.1,top=0.90,right=0.9,bottom=0.1) fig_pp.canvas.set_window_title("ScE - Hydrologie -Démo Gumbel") -fig_pp.suptitle(f"Démo Gumbel : tirages et leurs périodes de retour 'empiriques") +fig_pp.suptitle(f"Démo Gumbel : tirages et leurs périodes de retour empiriques") ax_T.set_xlabel("Période de retour (années)") -# LES OBS -courbe_Gumbel1, = ax_chrono.plot(range(len(serie_Gumbel.serie_chrono)), serie_Gumbel.serie_chrono, ls='--') -courbe_Gumbel = ax_chrono.scatter(range(len(serie_Gumbel.serie_chrono)), serie_Gumbel.serie_chrono, c=serie_Gumbel.serie_couleurs, alpha=0.7, label= f"Q(t) observé sur {N_total} années, ", marker="*", s=20) -#LA COURBE DE GUMBEL, inchangée (sauf si tracé en fréquence...) -courbe_Gumbel, = ax_T.plot(SerieGumbel.T_Gumbel_plot, serie_Gumbel.QGumbel_plot, color='red', alpha=0.7, linewidth=5, solid_capstyle='round', - zorder=10, label = "Q(T) du bassin versant", marker="None", ls='--', markersize=7) - -gr_est, x0_est = serie_Gumbel.gr_echantillon, serie_Gumbel.x0_echantillon - -courbe_estim_T_vlines = ax_T.vlines(x=T_emp_parametre(N_total, a, b), ymin=0, ymax=serie_Gumbel.serie_triee, color="purple", alpha=0.7, linewidth=2, - zorder=2, label= f"T ou f empirique, fonction de a et b", ls="--") -courbe_estim_Gumbel, = ax_T.plot([TdeQ_Gumbel(Q, gr_est, x0_est) for Q in serie_Gumbel.serie_triee], serie_Gumbel.serie_triee, color='blue', alpha=0.7, label=" ajustement Gumbel sur obs", - zorder=10, marker="x", markersize=7) - - -for ax_s in [ax_slide_a, ax_slide_b, ax_bouton, ax_chb]: +for ax_s in [ax_slide_a, ax_bouton_RAZ, ax_T2f, ax_slide_b, ax_bouton]: ax_s.xaxis.set_visible(False) ax_s.yaxis.set_visible(False) +""" for pos in ['right', 'top', 'bottom', 'left']: - ax_chb.spines[pos].set_visible(False) + ax_T2f.spines[pos].set_visible(False) +""" -print("ici") +# note : les variables après serie_Gumbel pourraient devenenir des attributs... +serie_Gumbel, courbe_Gumbel, gr_est, x0_est, courbe_estim_Gumbel, stemlines_emp, markerline_emp, baseline_emp = create_series('button_press_event') +ax_T.legend(bbox_to_anchor=(1.05, 0.05), loc='lower right') +print("Première série de max annuels créée") # nom connu même hors de la fonction pour éviter le GC ? # a @@ -351,15 +388,17 @@ slider_b = Slider( slider_b.on_changed(update_b) # bouton pour ajouter N_serie valeurs -valeurs_possibles_N = np.linspace(0, 100, 1) -bouton_obs = Button( - ax_bouton, f" Ajouter {N_serie} obs ", color="purple") - +couleur_bouton = 'linen' +bouton_obs = Button(ax_bouton, f" Ajouter {N_serie} obs ", color=couleur_bouton) bouton_obs.on_clicked(update_series) -# switch T / freq +# bouton pour ajouter N_serie valeurs +bouton_obs_RAZ = Button(ax_bouton_RAZ, f"Nouvelle série, {N_serie} obs ", color=couleur_bouton) +bouton_obs_RAZ.on_clicked(create_series) -chb_enT = CheckButtons(ax_chb, [ "axe des x en fréquence (de 0 à 1)"], [False]) +# switch T / freq +bouton_T2F = Button(ax_T2f, "axe des x en T => fréquence (de 0 à 1) ", color=couleur_bouton) +bouton_T2F.on_clicked(switch_freq) """ for rect in chb_enT.rectangles: rect.set_width(0.1) @@ -367,10 +406,7 @@ for rect in chb_enT.rectangles: rect.xy = (0.05,0) """ -chb_enT.on_clicked(switch_freq) - -ax_T.legend(title="formules", bbox_to_anchor=(1.05, 0.10), loc='lower right') #plt.tight_layout() #fig_pp.savefig("ma_figure.png") #fig_pp.canvas.draw()