diff --git a/Atelier_MatPlotLib_2021_part1.py b/Atelier_MatPlotLib_2021_part1.py new file mode 100644 index 0000000000000000000000000000000000000000..72218763cb5845f836d098df5f1a5ee8fc80f406 --- /dev/null +++ b/Atelier_MatPlotLib_2021_part1.py @@ -0,0 +1,1269 @@ +# Christine Poulard, mars 2021 +# Atelier d'initiation à MatplotLib + +""" +# LES IMPORTS - jamais d'import avec étoile ! +import mon_module # ensuite on appellera les fonctions du module avec mon_module.une_fonction + # mon_module = espace de nommage +import mon_module_avec_un_nom_complique as momo # ALIAS : ensuite on appellera les fonctions avec momo.une_fonction +from mon_module import une_fonction_utile, une_autre_fonction_utile + # import sélectif : je peux appeler une_fonction_utile (pas besoin de préciser l'espace de nommage + #risque de confusion (exemple d'un objet Polygon, avec un nom commun à plusieurs modules) +from mon_module_Truc import une_fonction_utile as truc_fu # la fonction a un alias que je choisis de manière à être simple mais non ambigu +""" + +# la ligne "de base" pour travailler avec matplotlib.pyplot, avec l'alias plt par convention +import matplotlib.pyplot as plt + +# des éléments complémentaires (on verra leur utilité) +import matplotlib.gridspec as gridspec +import matplotlib.dates as mpldates # https://matplotlib.org/examples/api/date_demo.html +from matplotlib.dates import DateFormatter +import matplotlib.colors as mocolor +from matplotlib.patches import Rectangle +from matplotlib.colors import ListedColormap +from matplotlib.collections import PatchCollection + +# gestion des fichiers et répertoires +import os +from pathlib import Path + +# une astuce pour aller chercher un fichier, même sans construire d'interface +from tkinter.filedialog import askopenfilename + +# le module "standard" de gestion des dates +from datetime import datetime, timedelta + +# le module de DataFrames +import pandas as pd + +# pour travailler avec de "vrais" vecteurs et matrices typées (calcul numérique performant) +import numpy as np + +# un prétexte pour parler des conteneurs de Python +from collections import OrderedDict + +# pour exporter +import pickle as pl + + +# CONSTANTES - convention : en majuscule + +# les noms de fichiers de données +REP_DONNEES = "C:/WorkSpace/2021-Tuto-Python/Code/donnees" # remplacez par votre chemin +TD4_ENTPE_TPQ_original = "TD4-donneesTPQ.txt" # date au format "janv-00" : bon exercice pour "parser" en utilisant un dico +TD4_ENTPE_pv = "ChroniquesTPluieQ_pointvirgule.csv" # même données avec des dates au format JJ/MM/AAAA, séparateur = ; +TD4_ENTPE_tab = "ChroniquesTPQ_tabulations.txt" # même données avec des dates au format JJ/MM/AAAA, séparateur = blanc ou tabulation + +HYDRO_QJO = "B2220010_qj_hydro2_2019.txt" +HYDRO_Qt = "B2220010_qtvar.txt" +HYDROQJ = "Y2372010_qj.csv" +CHAMP_BIN = "chronique_bloc_38_57_test2.bin" +CHAMP_GRID = "Panthere_20160512_LimBvGC_zoom1_0_Champ journalier.grd" + +trace_plt = True +trace_pd = True + +# CLASSES (même si en fait l'ordre importe peu...) + +# FONCTIONS + +# GRAPHIQUE SIMPLE + +# format Hydro2 "QJO" + +def lecteur_qj0_to_ts(nom_fichier, trace=True): + """ + Lecture d'un fichier chronique QJ0 pour la création d'un objet de type Pandas.Series + utilise le context manager with open(nom_fichier, 'r') as fichier, l'instructions readline et une boucle sur les lignes + :param nom_fichier: chemin complet vers le fichier au format Hydro2 "QJ0" + :param trace: booléen, si oui on trace un graphique simple + :return: Pandas.Series + """ + dico_qj = dict() + code_station = None + + with open(nom_fichier, 'r') as fichier: + while code_station is None: + # lecture d'une ligne à la fois + ligne = fichier.readline() + if ligne[0:3] == "950": # du premier caractère (rang 0) au 3e (rang 3 exclu) + vecteur = ligne.strip().split(";") + code_station = vecteur[1].strip() + nom_station = vecteur[2].strip() + # normalement, on a trové 950 et on continue + # un fichier est ITERABLE : boucle de lecture de toutes les lignes restantes du fichier + for ligne in fichier: + if "QJO" in ligne and code_station is not None: + # on a vérifié que la ligne contient QJO ; on s'attend à QJO;B2220010;19680627;7330.000;C;9; + # on découpe selon les ";" en une liste de chaîne de caracteres + liste_de_strings = ligne.strip().split(";") + # on vérifie que le 2e item correspond au code station attendu + # et on va extraire une info AAAAMMJJ du 3e item puis lire la valeur numérique du 4e + if liste_de_strings[1].strip() == code_station: + date_amj = liste_de_strings[2].strip() + annee = date_amj[0:4] + mois = date_amj[4:6] + jour = date_amj[6:8] + debit_lu = liste_de_strings[3].strip() + # tous ces éléments sont des STRING = CHAINES DE CARACTERES ; on a besoin de les convertir en nombres : int ou float + date = datetime(int(annee), int(mois), int(jour)) # objet de type datetime + # j'ajoute un élément au dictionnaire, de CLE date (objet date) et de VALEUR débit_lu converti en m3/S + dico_qj[date] = float(debit_lu) / 1000 + + + # on regarde ce que ça donne, au plus simple + # à savoir : les méthodes de dictionnaire keys() et values() ne renvoient pas une liste mais une vue + # donc on doit convertir en liste ; matplotlib ne sait pas gérer les dictionnaires tels quels + plt.plot(list(dico_qj.keys()), list(dico_qj.values())) + plt.title(nom_station) + plt.ylabel("QJ, débit moyen journalier (m3/s)") + plt.show() + # le programme s'arrête ici jusqu'à ce que l'on ferme la figure + + # je vais maintenant convertir mon dictionnaire en pandas.Series, type qui offre des fonctionnalités intéressantes + + print(f"Lecture terminée, de {min(dico_qj.keys())} à {max(dico_qj.keys())} ") + print(f" {len(dico_qj)} valeurs lues, de {min(dico_qj.items())} à {max(dico_qj.items())} ") + print(f" Code station = {code_station} , nom = {nom_station}") + + qj_series = pd.Series(dico_qj, name=nom_station + ' (QJO)').resample("1D").asfreq() + qj_series.sort_index(inplace=True) + + # on va utiliser le wrapper de pandas pour tracer : objet_pandas.plot + if trace: + print( "on va utiliser le wrapper de pandas pour tracer" ) + fig, ax = plt.subplots(figsize=(10, 5)) + + qj_series.plot(drawstyle="steps-post") + ax.set_ylabel("QJ, débit moyen journalier (m3/s)") + + fig.legend() + ax.set_title("Avec pandas QHydro2 QJ0, station " + nom_station ) + + plt.show() + + return qj_series + + +def donnees_TD_ETP_csv(nom_fichier, separateur=";"): + + """ + Lecteur du fichier TD4 ChroniquesTPluieQ_pointvirgule + caractéristiques : les dates sont bien reconnaissables, le séparateur de champs est le ; + on a donc définir un argument "facultatif" avec une valeur par défaut, si on ne précise rien le séparateur sera bien le ";" + version "compacte" mais il serait sans doute possible de lire direcement les dates avec les arguments supplémentaires + ..., parse_dates=True, dayfirst=True, infer_datetime_format=True,index_col=[0] ) + mais ça n'a pas marché... alors on passera par une étape intermédiaire + + """ + #note : # https: // stackoverflow.com / questions / 25416955 / plot - pandas - dates - in -matplotlib + + # fonction imbriquée dans la première, pour la mise en forme des données + # format the coords message box + def un_chiffre_apres_la_virgule(x): + # return '%1.1f unités' % x + return f"{x:.1f} unités" + + DF_TD4 = pd.read_csv(nom_fichier, sep=separateur, decimal=',') + + #on affiche les 5 premières lignes + DF_TD4.head(5) + + nom_colonnes = DF_TD4.columns.tolist() + print("Noms de colonnes lus dans le csv : ", nom_colonnes) + + # on affiche les 15 premières valeurs de la colonne n°0 + print(DF_TD4[nom_colonnes[0]][:15]) + + # pour assigner un format date à la première colonne, on a plusieurs possibilités : + # une façon "besogneuse" en découpant et collant les morceaux, comme à la première étape + # jmas = [date_str.split('/') for date_str in DF_TD4[nom_colonnes[0]]] # jmas est une liste de listes de 3 items + # dates_dt = [[datetime(int(a), int(m), int(j))] for j, m, a in jmas] # for j, m, a in jmas : on unpacke la liste + + # puisqu'il y a des séparateurs on peut aussi utiliser un lecteur de format du module datetime + # DF_TD4[nom_colonnes[0]].apply(lambda x: datetime.strptime(str(x), "%d/%m/%Y")) + + # ou enfin une méthode élégante de pandas, qui "se débrouille pour lire une date si c'est une date" + # date_au_format_pandas = pd.to_datetime(un_truc_nimporte_comment_qui_est_une_date) + # piège ; on ne sait jamais si c'est MMDD ou DDMM : l'argument dayfirst=True permet de cadrer le déchiffrage + + verif_conversion_dates = True + if verif_conversion_dates : + liste_dates_td = pd.to_datetime(DF_TD4[nom_colonnes[0]], dayfirst=True) # dayfirst est important ! + print("vérif conversion dates : ", liste_dates_td[:15]) + # DF_TD4[nom_colonnes[0]]= pd.to_datetime(DF_TD4[nom_colonnes[0]], dayfirst=True) + + # une fois convaincus, on peut faire la conversion directement dans la colonne + DF_TD4[nom_colonnes[0]] = pd.to_datetime(DF_TD4[nom_colonnes[0]], dayfirst=True) + + # sinon il y aurait une façon "besogneuse" : + # DF_TD4[nom_colonnes[0]].apply(lambda x: datetime.strptime(str(x), "%d/%m/%Y")) + + # on déclare comme index la colonne, avec les dates ; elle prend donc un statut particulier + DF_TD4.set_index(nom_colonnes[0], inplace=True) + + # on met à jour la liste des colonnes (on a supprimé une colonne "dates") + nom_colonnes = DF_TD4.columns.tolist() + print("Noms des colonnes après avoir défini l'index : ", nom_colonnes) + + print("Type de liste dates td", type(liste_dates_td[0]), liste_dates_td[0]) + print("Type de la première colonne (0) ", type(DF_TD4[nom_colonnes[0]][0]), DF_TD4[nom_colonnes[0]][0]) + + DF_TD4.head(5) + + fig, ax = plt.subplots() # on verra juste après cette syntaxe + DF_TD4.plot(ax=ax) + fig.suptitle("En utilisant les possibilités de pandas") + + plt.legend() + + # plt.gca().format_xdata = mpldates.DateFormatter('%Y/%m') + # plt.gca().format_ydata = un_chiffre_apres_la_virgule + # plt.gcf().autofmt_xdate() # sur figure + plt.show() + + return DF_TD4 + + +def donnees_TD_ETP_2subplots(nom_fichier): + # le début est identique à donnees_TD_ETP_csv + + DF_TD4 = pd.read_csv(nom_fichier, sep=';', decimal=',') + nom_colonnes = DF_TD4.columns.tolist() + DF_TD4[nom_colonnes[0]] = pd.to_datetime(DF_TD4[nom_colonnes[0]], dayfirst=True) + + # on définit index=première colonne, la colonne "date" ,'existe donc plus en temps que telle + DF_TD4.set_index(nom_colonnes[0], inplace=True) + + liste_dates = [date_pd.to_pydatetime() for date_pd in DF_TD4.index] + + DF_TD4.head(5) + nom_colonnes = DF_TD4.columns.tolist() + print("Noms de colonnes lus dans le csv : ", nom_colonnes) + + # on découpe la figure en deux subplots + fig, (ax_pluie, ax_q) = plt.subplots(ncols=1, nrows=2, sharex=True) + fig.subplots_adjust(bottom=0.15) + fig.suptitle("Forçages en haut, réponse du bassin en bas") + + etiquette_pluie = nom_colonnes[1] + ax_pluie.set_ylabel(etiquette_pluie, color='lightblue') + ax_pluie.vlines(x=liste_dates, ymin=0, ymax=DF_TD4[etiquette_pluie].tolist(), color='lightblue', lw=2, + label=etiquette_pluie) + ax_pluie.invert_yaxis() + + ax_t = ax_pluie.twinx() + etiquette_temperatures = nom_colonnes[0] + ax_t.set_ylabel(etiquette_temperatures) + ax_t.plot(liste_dates, DF_TD4[etiquette_temperatures].tolist(), marker='*', color='orange', ls=':', + label=etiquette_temperatures, zorder=50) + + etiquette_debit = nom_colonnes[2] + ax_q.set_ylabel(etiquette_debit, color='blue') + ax_q.plot(liste_dates, DF_TD4[etiquette_debit].tolist(), marker='>', color='blue', ls=':', label=etiquette_debit) + + fig.legend(bbox_to_anchor=(1, 0), loc="lower right", + bbox_transform=fig.transFigure, ncol=3) + + # plt.gca().format_xdata = mpldates.DateFormatter('%Y/%m') + # plt.gca().format_ydata = un_chiffre_apres_la_virgule + # plt.gcf().autofmt_xdate() # sur figure + + #le module pickle + # nom_fichier_pickle = Path(nom_fichier).with_suffix('.pickle') + # pl.dump(fig, open(nom_fichier_pickle, 'wb')) + # print(nom_fichier_pickle) + + plt.show() + + return DF_TD4 + + +def trace_avec_plt(liste_dates, valeurs, type_graphe="plot"): + temps = datetime.now() - debut + + # plt.suptitle("trace_avec_plt - fig.suptitle") + + if type_graphe == "plot": + + plt.plot(liste_dates, valeurs) + plt.title("Avec pyplot, plot") + + elif type_graphe == "stem": + plt.stem(liste_dates, valeurs) + plt.title("Avec pyplot, stem") + + elif type_graphe == "hlines": + plt.hlines(y=valeurs, xmin=liste_dates, xmax=[date + timedelta(days=30) for date in liste_dates]) + + elif type_graphe == "vlines": + plt.vlines(x=liste_dates, ymin=0, ymax=valeurs) + + # pour améliorer + plt.xticks(rotation=45) + plt.tight_layout(True) + # plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0) + # plt.tight_layout({'rect': [0, .15, 1, 0.9]}, w_pad=0.5, h_pad=1.0) + plt.subplots_adjust(bottom=0.2) + + # fig.autofmt_xdate() + + val_moy = max(valeurs) / 2 + + # tests stem et vline sur qq valeurs + # plt.stem([liste_dates[0],liste_dates[-1]], [val_moy, val_moy ]) + # plt.vlines([liste_dates[5], liste_dates[-10]], [0, 0], [val_moy, val_moy], colors=["red", "green"]) + plt.title("Avec pyplot, " + type_graphe) + plt.gcf().canvas.set_window_title("Avec_pyplot_" + type_graphe) + + plt.show() + print("temps écoulé Pyplot avec plot:", temps) + + # plt.clf() + + return temps + + +def trace_au_choix(serie, type_graphe="plot"): + temps = datetime.now() - debut + + if type_graphe == "plot": + + serie.plot() + + elif type_graphe == "hlines": + plt.hlines(y=serie, xmin=serie.index, xmax=[date + timedelta(days=30) for date in serie.index]) + + plt.title("Avec pyplot, hines") + + plt.show() + + print("temps écoulé, fonction trace_au_choix :", temps) + # plt.clf() + + return temps + + +def tracer_DF_lamedeau_moyennes_mobiles(series_or_df_lamedeau): + # format the coords message box + def un_chiffre_apres_la_virgule(x): + # return '%1.1f unités' % x + return f"{x:.1f} mm/5 min" + + # DF_moymobile_1j et 30 jours définis pour le plot mais non nommés + + if type(series_or_df_lamedeau) == pd.Series: + df_ler5min = series_or_df_lamedeau.to_frame() + else: + df_ler5min = series_or_df_lamedeau # deepcopy + df_ler5min.columns = ["Lame d'eau radar à 5 mm, en mm"] + df_ler5min.columns.name = 'Chroniques' + + fig, (ax_moy, ax_ler) = plt.subplots(nrows=2, ncols=1, sharex=True) + fig.subplots_adjust(bottom=0.3) + + fig.suptitle("Lames d'eau radar et cumuls, en utilisant pandas") + + couleur_5min = 'blue' + ax_ler.set_ylabel("Lame d'eau radar \n (mm en 5 mm)", color=couleur_5min) + # méthode plot de pandas appliquée à un dataframe + df_ler5min.plot(ax=ax_ler, color=couleur_5min) + + couleur_24h = 'red' + ax_moy.set_ylabel("Cumuls sur 24 h (mm)", color=couleur_24h) + df_24h = df_ler5min.rolling('1d').sum() + df_24h.columns = ["Cumuls mobiles sur 24h"] + df_24h.plot(ax=ax_moy, color=couleur_24h, label="ça sert à rien") + + couleur_30j = 'orange' + ax_moy_30j = ax_moy.twinx() + ax_moy_30j.set_ylabel("Cumuls sur 30 jours", color=couleur_30j) + + df_30j = df_ler5min.rolling('30d').sum() + df_30j.columns = ["Cumuls mobiles sur 30 jours"] + df_30j.plot(ax=ax_moy_30j, color=couleur_30j) + + for ax in [ax_ler, ax_moy, ax_moy_30j]: + ax.legend().set_visible(False) + + fig.legend(loc='lower center', ncol=2) + + ax_ler.format_ydata = un_chiffre_apres_la_virgule + ax_moy.format_ydata = un_chiffre_apres_la_virgule + ax_moy_30j.format_ydata = un_chiffre_apres_la_virgule + + # plt.gca().format_xdata = mpldates.DateFormatter('%Y/%m') + # plt.gca().format_ydata = un_chiffre_apres_la_virgule + # plt.gcf().autofmt_xdate() # sur figure + plt.show() + + +def trace_3_courbes_avec_pandas(ts_lamedeau, ts_mensuel, ts_journalier): + print("Moyennes pdt fixes") + + fig = plt.figure("Chroniques_pandas", figsize=[10, 5]) # tight_layout=True, + fig.suptitle("Avec pandas, plus moyennes mensuelles en errorbars") + # https://matplotlib.org/gallery/userdemo/demo_gridspec03.html#sphx-glr-gallery-userdemo-demo-gridspec03-py + gs = gridspec.GridSpec(nrows=2, ncols=1, height_ratios=[10, 1]) + ax1 = fig.add_subplot(gs[0]) + + # ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + # title="Avec pandas, données moyennées (pas de temps fixe)", + # color='purple') + ts_lamedeau.plot(label="lame d'eau à 5 min", color='purple', ax=ax1) + (handles1, labels1) = ax1.get_legend_handles_labels() + + ax2 = ax1.twinx() + + moyenne_des_mois = ts_mensuel.mean() + moyenne_des_ler5min = ts_lamedeau.mean() + print("moyenne des mois = ", moyenne_des_mois, " à comparer avec ", moyenne_des_ler5min) + + ts_mensuel.plot(label=' cumul mensuel', color='lightblue', ax=ax2, ls=':') + ax2.errorbar(ts_mensuel.index, ts_mensuel, label=' cumul mensuel avec figuré errorbar', xerr=timedelta(days=30), + ls='None', color='blue', marker=">", xuplims=True) + + debut_pour_plt = pd.to_datetime(date_debut_pd) + fin_pour_plt = pd.to_datetime(date_fin_pd) + + # TESTS AVEC LES VLINE avec s + # ts_journalier.plot(label=' moyenne journalière', color='orange', ax=ax2) + # https: // stackoverflow.com / questions / 5902371 / matplotlib - bar - chart - with-dates + # ax1.xaxis_date() + ts_journalier.plot(label=' moyenne journalière', color='orange', ax=ax2) + (handles2, labels2) = ax2.get_legend_handles_labels() + + plt.legend(handles1 + handles2, labels1 + labels2, bbox_to_anchor=(0.9, 0.05), loc="lower right", # mode="expand", + bbox_transform=fig.transFigure, ncol=2) # loc='best') + plt.show() + # plt.clf() + + +def trace_3_courbes_avec_pandas_donc_vlines(ts_lamedeau, ts_mensuel, ts_journalier): + print("Moyennes pdt fixes, trace_3_courbes_avec_pandas_dont_vlines") + + # ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + # title="Avec pandas, données moyennées (pas de temps fixe)", + # color='purple') + + fig = plt.figure("avec_pandas_jours_vlines", tight_layout=True) + gs = gridspec.GridSpec(nrows=2, ncols=1, height_ratios=[10, 1]) + ax1 = fig.add_subplot(gs[0]) + + ts_lamedeau.plot(label="lame d'eau à 5 min", title="Avec pandas et vlines", color='purple', ax=ax1) + (handles, labels) = ax1.get_legend_handles_labels() + + ax2 = ax1.twinx() + + # ts_journalier.plot(label=' moyenne journalière', color='orange', ax=ax2) + # https: // stackoverflow.com / questions / 5902371 / matplotlib - bar - chart - with-dates + # ax1.xaxis_date() + + moyenne_des_mois = ts_mensuel.mean() + print("moyenne des mois = ", moyenne_des_mois) + + # graphique des mois + ts_mensuel.plot(label=' cumuls mensuels (pd plot)', color='lightblue', ax=ax2) + ax2.errorbar(ts_mensuel.index, ts_mensuel, label='cumuls mensuels (figuré errorbar)', xerr=timedelta(days=30), + ls='None', color='blue', marker=">", xuplims=True) + + debut_pour_plt = pd.to_datetime(date_debut_pd) + fin_pour_plt = pd.to_datetime(date_fin_pd) + + # TESTS AVEC LES AX.H/V.LINE avec s + # il faut un autre plot déjà sur le même ax + # ts_journalier.plot(label=' moyenne journalière', color='orange', ax=ax2, ls=':') + ax2.vlines(x=ts_journalier.index, ymin=0, ymax=ts_journalier, label="cumuls journaliers (vlines)", color='orange', + lw=5, alpha=0.8) + + # PB avec STEM : + # ValueError: view limit minimum -453626.8500000001 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units + # + stem() got an unexpected keyword argument 'use_line_collection' + # on teste d'abord avec les mois ?? + # ax2.stem(ts_journalier.index, ts_journalier) # use_line_collection=True) #, color='red') + # print(type(ts_mensuel.index[0])) + # print(ts_mensuel.index) + # ax2.stem([pd.to_datetime(date) for date in ts_mensuel.index], ts_mensuel) + + (handles2, labels2) = ax2.get_legend_handles_labels() + + plt.legend(handles + handles2, labels + labels2, bbox_to_anchor=(1, 0.1), loc="lower right", # mode="expand", + bbox_transform=fig.transFigure, ncol=2) # loc='best') + plt.show() + # plt.clf() + + +# moyennes par MOIS avec des rectangles +def trace_mensuel_avec_rectangles(ts_lamedeau, ts_mensuel, ts_journalier=None, trace_rect_mensuels=False): + debut = datetime.now() + + """ + si DF + ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + title="Avec rectangles,5 min et cumuls mensuels (pas de temps fixe)", + color='purple', zorder=10) + """ + fig, ax1 = plt.subplots("chroniques_mois_rectangles", figsize=(7, 4)) + ts_lamedeau.plot(title="trace_mensuel_avec_rectangles (cumuls pas de temps fixe)", label="lames d'eau à 5 min", + color='purple', zorder=10, ax=ax1) + ax1.set(ylabel="Lames d'eau à 5 min") + (handles, labels) = plt.gca().get_legend_handles_labels() + + # pas possible de mettre un 2e axe rien qu'avec des rectangles... DONC il faut mettre une ligne "guide" avec un plot + # moyenne_des_mois = ds_mensuel["lames d'eau en mm"].mean() + date_debut_pd = ts_lamedeau.index[0] + date_fin_pd = ts_lamedeau.index[-1] + + ax2 = ax1.twinx() + + ts_debutfin = pd.Series([ts_mensuel.mean(), ts_mensuel.mean()], index=[date_debut_pd, date_fin_pd]) + + ts_debutfin.plot(ls=':', label='moyenne des cumuls mensuels', ax=ax2) + ax2.set(ylabel="cumuls (sur la durée, 1 j ou 1 mois)") + + for debut_rect, valeur in zip(ts_mensuel.index, ts_mensuel): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + + print(debut_rect, valeur, code_couleur) + # patch = patches.Rectangle(xy, w, h, linewidth=1, edgecolor=edgecolor, facecolor=facecolor) + if trace_rect_mensuels: + ax2.add_patch(Rectangle((debut_rect, 0.1), -timedelta(days=30), valeur, color=code_couleur, alpha=0.8)) + + # pause=input("fin des rectangles par mois ! ") + + """ + # avec PatchCollection (pb avec dates ??) + notre_cmap = ListedColormap(color_list) + patches_collection = PatchCollection(patch_list, cmap=notre_cmap, alpha=1) + patches_collection.set_array(np.arange(len(patch_list))) + ax1.add_collection(patches_collection, zorder=5) + """ + ts_journalier.plot(color='red', ax=ax2, label='cumul journalier') + + (handles2, labels2) = plt.gca().get_legend_handles_labels() + # ax1.plot(ts_journalier.index, ts_journalier, label=' pyplot', + # ls=':', color='yellow', lw=5, alpha=0.5) + + # ax1.errorbar(ts_journalier.index, ts_journalier, label=' moyenne journalière par errorbar', xerr=timedelta(days=1), + # ls='None', color='orange', marker=">", xuplims=True) + + # Legende commune + # plt.gca().legend(handles+handles2,labels+labels2) + box = plt.gca().get_position() + plt.gca().set_position([box.x0, box.y0, box.width * 0.8, box.height]) + fig.legend(loc=7) + + # max_valeur = max(df_lamedeau["lames d'eau en mm"].max(), df_mensuel["lames d'eau en mm"].max()) + # min_valeur = min(0, df_lamedeau["lames d'eau en mm"].min(), df_mensuel["lames d'eau en mm"].min()) + # ax1.set_ylim(min_valeur, df_mensuel["lames d'eau en mm"].max()*1.1) + # ax1.set_ylim(min_valeur, max_valeur * 1.1) + + ax1.set_ylim(0, ts_lamedeau.max() * 1.1) + ax2.set_ylim(0, ts_mensuel.max() * 1.1) + + # jours : Memoruy Error avec vlines ? + """ + color_list = [] + for debut_rect, valeur in zip(df_journalier.index, df_journalier["lames d'eau en mm"]): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + + color_list.append(code_couleur) + + # colors avec un s car il y a une liste + ax2.vlines(df_journalier.index, 0, df_journalier["lames d'eau en mm"], colors=color_list) + """ + temps = datetime.now() - debut + plt.show() + print("temps écoulé Pandas avec mois en rectangles", temps) + # plt.close(fig) + + +def trace_mensuel_avec_hlines(ts_lamedeau, ts_mensuel, ts_journalier=None, trace_hlines=False): + debut = datetime.now() + + """ + si DF + ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + title="Avec rectangles,5 min et cumuls mensuels (pas de temps fixe)", + color='purple', zorder=10) + """ + fig = plt.figure(figsize=(7, 4)) + # on crée un emplacement vide + gs = gridspec.GridSpec(nrows=2, ncols=1, height_ratios=[10, 1]) + ax1 = fig.add_subplot(gs[0]) + ts_lamedeau.plot(title="tracé cumuls_mensuel_avec_hlines ", label="lames d'eau à 5 min", color='purple', + zorder=10, ax=ax1) + ax1.set(ylabel="Lames d'eau à 5 min") + (handles, labels) = plt.gca().get_legend_handles_labels() + + # pas possible de mettre un 2e axe rien qu'avec des rectangles... DONC il faut mettre une ligne "guide" avec un plot + # moyenne_des_mois = ds_mensuel["lames d'eau en mm"].mean() + date_debut_pd = ts_lamedeau.index[0] + date_fin_pd = ts_lamedeau.index[-1] + + ax2 = ax1.twinx() + + ts_debutfin = pd.Series([ts_mensuel.mean(), ts_mensuel.mean()], index=[date_debut_pd, date_fin_pd]) + + ts_debutfin.plot(ls=':', label='moyenne des cumuls mensuels', ax=ax2) + ax2.set(ylabel="cumuls (sur la durée, 1 j ou 1 mois)") + + codes_couleur = [] + for debut_rect, valeur in zip(ts_mensuel.index, ts_mensuel): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + + codes_couleur.append(code_couleur) + + print(debut_rect, valeur, code_couleur) + + if trace_hlines: + ax2.hlines(y=ts_mensuel, xmax=ts_mensuel.index, + xmin=[date - timedelta(days=30) for date in ts_mensuel.index], + label="cumuls mensuels", color=codes_couleur, lw=3, alpha=0.8) + + ts_journalier.plot(color='red', ax=ax2, label='cumuls journaliers') + + (handles2, labels2) = plt.gca().get_legend_handles_labels() + + # Legende commune + + plt.legend(handles + handles2, labels + labels2, bbox_to_anchor=(1, 0.01), loc="lower right", # mode="expand", + bbox_transform=fig.transFigure, ncol=2) + """ + box = plt.gca().get_position() + plt.gca().set_position([box.x0, box.y0, box.width * 0.8, box.height]) + fig.legend(loc=7) + """ + ax1.set_ylim(0, ts_lamedeau.max() * 1.1) + ax2.set_ylim(0, ts_mensuel.max() * 1.1) + + temps = datetime.now() - debut + plt.show() + print("temps écoulé Pandas avec mois en rectangles", temps) + # plt.clf() + + +def HautBas_trace_mensuel_avec_rectangles(ts_lamedeau, ts_mensuel, ts_journalier=None, trace_rect_mensuels=False): + debut = datetime.now() + + """ + si DF + ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + title="Avec rectangles,5 min et cumuls mensuels (pas de temps fixe)", + color='purple', zorder=10) + """ + # d'après cheatsheet pbpython + fig, (ax_cumul, ax_5min) = plt.subplots(nrows=2, ncols=1, sharex=True, figsize=(7, 4)) + fig.suptitle("Lames d'eau à 5 min (bas) et cumuls journaliers et mensuels (haut)") + ax_cumul.set(ylabel="cumuls") + ax_5min.set(ylabel="lame d'eau \n à 5 min") + + ts_lamedeau.plot(label="lames d'eau à 5 min", color='purple', zorder=10, ax=ax_5min) + plt.legend() + + # pas possible de mettre un 2e axe rien qu'avec des rectangles... DONC il faut mettre une ligne "guide" avec un plot + # moyenne_des_mois = ds_mensuel["lames d'eau en mm"].mean() + date_debut_pd = ts_lamedeau.index[0] + date_fin_pd = ts_lamedeau.index[-1] + + ts_debutfin = pd.Series([ts_mensuel.mean(), ts_mensuel.mean()], index=[date_debut_pd, date_fin_pd]) + + ts_debutfin.plot(ls=':', label='moyenne des cumuls mensuels', ax=ax_cumul) + + # TESTS : on enlève les rectangles + for debut_rect, valeur in zip(ts_mensuel.index, ts_mensuel): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + + print(debut_rect, valeur, code_couleur) + # patch = patches.Rectangle(xy, w, h, linewidth=1, edgecolor=edgecolor, facecolor=facecolor) + if trace_rect_mensuels: + ax_cumul.add_patch(Rectangle((debut_rect, 0.1), -timedelta(days=30), valeur, color=code_couleur, alpha=0.8)) + + # pause=input("fin des rectangles par mois ! ") + + # TESTS : on enlève aussi le journalier - plot ou vlines ? + # ts_journalier.plot(color='red', ax=ax_cumul, label='cumul journalier') + + # ax_cumul.plot(ts_journalier.index, ts_journalier, label=' pyplot', + # ls=':', color='yellow', lw=5, alpha=0.5) + + ax_cumul.vlines(x=ts_journalier.index, ymin=0, ymax=ts_journalier, label="cumuls journaliers (vlines)", + color='red', lw=1, alpha=0.8) + + ax_cumul.legend() + + # max_valeur = max(df_lamedeau["lames d'eau en mm"].max(), df_mensuel["lames d'eau en mm"].max()) + # min_valeur = min(0, df_lamedeau["lames d'eau en mm"].min(), df_mensuel["lames d'eau en mm"].min()) + # ax1.set_ylim(min_valeur, df_mensuel["lames d'eau en mm"].max()*1.1) + # ax1.set_ylim(min_valeur, max_valeur * 1.1) + + ax_5min.set_ylim(0, ts_lamedeau.max() * 1.1) + ax_cumul.set_ylim(0, ts_mensuel.max() * 1.1) + + # jours : Memoruy Error avec vlines ? + """ + color_list = [] + for debut_rect, valeur in zip(df_journalier.index, df_journalier["lames d'eau en mm"]): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + + color_list.append(code_couleur) + + # colors avec un s car il y a une liste + ax2.vlines(df_journalier.index, 0, df_journalier["lames d'eau en mm"], colors=color_list) + """ + temps = datetime.now() - debut + plt.show() + print("temps écoulé Pandas avec mois en rectangles", temps) + # plt.clf() + + +def HautBas_trace_mensuel_avec_hlines(ts_lamedeau, ts_mensuel, ts_journalier=None, trace_hlines_mensuels=True): + debut = datetime.now() + + """ + si DF + ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + title="Avec rectangles,5 min et cumuls mensuels (pas de temps fixe)", + color='purple', zorder=10) + """ + # d'après cheatsheet pbpython + fig, (ax_cumul, ax_5min) = plt.subplots(nrows=2, ncols=1, sharex=True, figsize=(7, 4)) + fig.suptitle("Lames d'eau à 5 min (bas) et cumuls journaliers et mensuels (haut)") + ax_cumul.set(ylabel="cumuls") + ax_5min.set(ylabel="lame d'eau \n à 5 min") + + ts_lamedeau.plot(label="lames d'eau à 5 min", color='purple', zorder=10, ax=ax_5min) + plt.legend() + + # pas possible de mettre un 2e axe rien qu'avec des rectangles... DONC il faut mettre une ligne "guide" avec un plot + # moyenne_des_mois = ds_mensuel["lames d'eau en mm"].mean() + date_debut_pd = ts_lamedeau.index[0] + date_fin_pd = ts_lamedeau.index[-1] + + ts_debutfin = pd.Series([ts_mensuel.mean(), ts_mensuel.mean()], index=[date_debut_pd, date_fin_pd]) + + ts_debutfin.plot(ls=':', label='moyenne des cumuls mensuels', ax=ax_cumul) + + # TESTS : on enlève les rectangles + couleurs = [] + for debut_rect, valeur in zip(ts_mensuel.index, ts_mensuel): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + couleurs.append(code_couleur) + + # patch = patches.Rectangle(xy, w, h, linewidth=1, edgecolor=edgecolor, facecolor=facecolor) + + # TESTS : on enlève aussi le journalier - plot ou vlines ? + # ts_journalier.plot(color='red', ax=ax_cumul, label='cumul journalier') + + # ax_cumul.plot(ts_journalier.index, ts_journalier, label=' pyplot', + # ls=':', color='yellow', lw=5, alpha=0.5) + if trace_hlines_mensuels: + ax_cumul.hlines(y=ts_mensuel, xmax=ts_mensuel.index, + xmin=[date - timedelta(days=30) for date in ts_mensuel.index], label="cumuls mensuels (hlines)", + color=couleurs, lw=1, alpha=0.9) + + ax_cumul.vlines(x=ts_journalier.index, ymin=0, ymax=ts_journalier, label="cumuls journaliers (vlines)", + color='red', lw=1, alpha=0.8) + + ax_cumul.legend() + + # max_valeur = max(df_lamedeau["lames d'eau en mm"].max(), df_mensuel["lames d'eau en mm"].max()) + # min_valeur = min(0, df_lamedeau["lames d'eau en mm"].min(), df_mensuel["lames d'eau en mm"].min()) + # ax1.set_ylim(min_valeur, df_mensuel["lames d'eau en mm"].max()*1.1) + # ax1.set_ylim(min_valeur, max_valeur * 1.1) + + ax_5min.set_ylim(0, ts_lamedeau.max() * 1.1) + ax_cumul.set_ylim(0, ts_mensuel.max() * 1.1) + + temps = datetime.now() - debut + plt.show() + print("temps écoulé Pandas avec mois en hlines", temps) + + +# todo : HautBas_trace_mensuel_avec_hlines_2y_en_haut +def HautBas_trace_mensuel_avec_hlines_2y_en_haut(ts_lamedeau, ts_mensuel, ts_journalier=None, + trace_hlines_mensuels=True): + debut = datetime.now() + + """ + si DF + ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + title="Avec rectangles,5 min et cumuls mensuels (pas de temps fixe)", + color='purple', zorder=10) + """ + # https://stackoverflow.com/questions/22511550/gridspec-with-shared-axes-in-python + # fig, (ax_cumul, ax_5min) = plt.subplots(nrows=3, ncols=1, sharex=True, figsize=(7,4), gridspec_kw={'height_ratios': [5,5, 1]}) + fig, (ax_cumul, ax_5min) = plt.subplots(nrows=2, ncols=1, sharex=True, figsize=(8, 5)) + # tight_layout docs: [left, bottom, right, top] in normalized (0, 1) figure coordinates + # You can increase the space between suptitle and axes even more by lowering the rightest value: + fig.set_tight_layout({'rect': [0, .15, 1, 0.9], 'pad': 1.5, 'h_pad': 1.5}) + # fig.subplots_adjust(bottom=0.9) + fig.suptitle("Lames d'eau à 5 min (bas) et cumuls journaliers et mensuels (haut)") + ax_cumul.set(ylabel="cumuls mensuels)") + ax_5min.set(ylabel="lame d'eau \n à 5 min") + + ts_lamedeau.plot(label="lames d'eau à 5 min", color='purple', zorder=10, ax=ax_5min) + # plt.legend() + + # pas possible de mettre un 2e axe rien qu'avec des rectangles... DONC il faut mettre une ligne "guide" avec un plot + # moyenne_des_mois = ds_mensuel["lames d'eau en mm"].mean() + date_debut_pd = ts_lamedeau.index[0] + date_fin_pd = ts_lamedeau.index[-1] + + ts_debutfin = pd.Series([ts_mensuel.mean(), ts_mensuel.mean()], index=[date_debut_pd, date_fin_pd]) + + ts_debutfin.plot(ls=':', label='moyenne des cumuls mensuels', ax=ax_cumul) + + # TESTS : on enlève les rectangles + couleurs = [] + for debut_rect, valeur in zip(ts_mensuel.index, ts_mensuel): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + couleurs.append(code_couleur) + + # patch = patches.Rectangle(xy, w, h, linewidth=1, edgecolor=edgecolor, facecolor=facecolor) + + # TESTS : on enlève aussi le journalier - plot ou vlines ? + # ts_journalier.plot(color='red', ax=ax_cumul, label='cumul journalier') + + # ax_cumul.plot(ts_journalier.index, ts_journalier, label=' pyplot', + # ls=':', color='yellow', lw=5, alpha=0.5) + if trace_hlines_mensuels: + ax_cumul.hlines(y=ts_mensuel, xmax=ts_mensuel.index, + xmin=[date - timedelta(days=30) for date in ts_mensuel.index], label="cumuls mensuels (hlines)", + color=couleurs, lw=1, alpha=0.9) + ax_cumul.set_ylim(0, ts_mensuel.max() * 1.1) + + ax_cumul_j = ax_cumul.twinx() + ax_cumul_j.set(ylabel=("cumuls journaliers")) + ts_debutfin_j = pd.Series([ts_journalier.mean(), ts_journalier.mean()], index=[date_debut_pd, date_fin_pd]) + + ts_debutfin.plot(ls=':', label='moyenne des cumuls journaliers', ax=ax_cumul_j, color='orange') + ax_cumul_j.vlines(x=ts_journalier.index, ymin=0, ymax=ts_journalier, label="cumuls journaliers (vlines)", + color='red', lw=1, alpha=0.8) + + # ax_cumul.legend() + + # max_valeur = max(df_lamedeau["lames d'eau en mm"].max(), df_mensuel["lames d'eau en mm"].max()) + # min_valeur = min(0, df_lamedeau["lames d'eau en mm"].min(), df_mensuel["lames d'eau en mm"].min()) + # ax1.set_ylim(min_valeur, df_mensuel["lames d'eau en mm"].max()*1.1) + # ax1.set_ylim(min_valeur, max_valeur * 1.1) + + ax_5min.set_ylim(0, ts_lamedeau.max() * 1.1) + ax_cumul.set_ylim(0, ts_mensuel.max() * 1.1) + + # légende de figure + fig.legend(loc='lower center', mode="expand", borderaxespad=0, ncol=2) + + temps = datetime.now() - debut + plt.show() + print("temps écoulé Pandas avec mois en hlines, 2 aces des y en haut", temps) + + +def trace_bars_hack_rectangles(ts_lamedeau, ts_mensuel, ts_journalier, hack_rect_mensuels=False): + debut = datetime.now() + + """ + si DF + ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + title="Avec rectangles,5 min et cumuls mensuels (pas de temps fixe)", + color='purple', zorder=10) + """ + ax1 = ts_lamedeau.plot(label="lames d'eau à 5 min", + title="Avec collection de rectangles,5 min et cumuls mensuels (pas de temps fixe)", + color='purple', zorder=10) + + # pas possible de mettre un 2e axe rien qu'avec des rectangles... DONC il faut mettre une ligne "guide" avec un plot + + ax2 = ax1.twinx() + + # moyenne_des_mois = ds_mensuel["lames d'eau en mm"].mean() + date_debut_pd = ts_lamedeau.index[0] + date_fin_pd = ts_lamedeau.index[-1] + + ts_debutfin = pd.Series([ts_mensuel.mean(), ts_mensuel.mean()], index=[date_debut_pd, date_fin_pd]) + + ts_debutfin.plot(ls=':', ax=ax2) + + # on prépare les rectangles + liste_rectangles = [] + for debut_rect, valeur in zip(ts_mensuel.index, ts_mensuel): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + if hack_rect_mensuels: + ax2.add_patch(Rectangle((debut_rect, 0.1), timedelta(days=30), valeur, color=code_couleur)) + + # print(debut_rect, valeur, code_couleur) + # alternative avec liste_rectangles.append puis ax2.add_collection + # descriptif : patch = patches.Rectangle(xy, w, h, linewidth=1, edgecolor=edgecolor, facecolor=facecolor) + # if hack_rect_mensuels: + # liste_rectangles.append(Rectangle((debut_rect, 0.1), timedelta(days=30), valeur, color=code_couleur)) + + # avec PatchCollection (pb avec dates ??) + # notre_cmap = ListedColormap(color_list) + # patches_collection = PatchCollection(liste_rectangles, match_original=True, alpha=1) + # patches_collection.set_array(np.arange(len(liste_rectangles))) + # ax2.add_collection(patches_collection, zorder=5) + + # ts_journalier.plot(color='red') + # ts_journalier.plot(label=' cumul journalier, pd', + # ls=':', color='yellow', lw=2, alpha=0.5, ax=ax2) + ax2.vlines(x=ts_journalier.index, ymin=0, ymax=ts_journalier, label="cumuls journaliers (vlines)", + color='orange', lw=5, alpha=0.8) + + # max_valeur = max(df_lamedeau["lames d'eau en mm"].max(), df_mensuel["lames d'eau en mm"].max()) + # min_valeur = min(0, df_lamedeau["lames d'eau en mm"].min(), df_mensuel["lames d'eau en mm"].min()) + # ax1.set_ylim(min_valeur, df_mensuel["lames d'eau en mm"].max()*1.1) + # ax1.set_ylim(min_valeur, max_valeur * 1.1) + + ax1.set_ylim(0, ts_lamedeau.max() * 1.1) + ax2.set_ylim(0, ts_mensuel.max() * 1.1) + plt.legend() + + # jours : Memoruy Error avec vlines ? + """ + color_list = [] + for debut_rect, valeur in zip(df_journalier.index, df_journalier["lames d'eau en mm"]): + if debut_rect.month in [12, 1, 2]: + code_couleur = 'blue' + elif debut_rect.month in [3, 4, 5]: + code_couleur = 'pink' + elif debut_rect.month in [6, 7, 8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + + color_list.append(code_couleur) + + # colors avec un s car il y a une liste + ax2.vlines(df_journalier.index, 0, df_journalier["lames d'eau en mm"], colors=color_list) + """ + temps = datetime.now() - debut + plt.show() + print("temps écoulé Pandas avec mois en rectangles 'patch collection' :", temps) + + return temps + + +if __name__ == '__main__': + + # Premières manipulation, plot simple + premier_atelier = False + if premier_atelier: + # définition d'un chemin, méthode filedialog + chemin_complet = askopenfilename() + if Path.is_file(Path(chemin_complet)): + ts = lecteur_qj0_to_ts(chemin_complet) + else: + print("chemin ", chemin_complet, " non valide") + + # Deuxième atelier, figure avec plusieurs courbes, 2e axe des y + deuxieme_atelier = True + chemin_complet = askopenfilename() + # donnees_TD_ETP_csv(chemin_complet) + donnees_TD_ETP_2subplots(chemin_complet) + +""" + +# données TD4 ENTPE +# nom_fichier_TD4 = "D:/2020-TraitementChroniques/TestsVisuChroniques/donnees/ChroniquesPluieT.csv" +nom_fichier_TD4 = "D:/2020-TraitementChroniques/TestsVisuChroniques/donnees/donnees.csv" +nom_rep = "D:/2020-TraitementChroniques/TestsVisuChroniques/donnees" + +print("Le chemin existe ? ... ", Path.is_dir(Path(nom_rep))) + +tracer_td4 = False + +if Path.is_file(Path(nom_fichier_TD4)) and tracer_td4: + print(f"traitement du fichier date, P, T : {nom_fichier_TD4} ") + + # DF_ETP = donnees_TD_ETP_besogneux(nom_fichier_TD4) + # DF_ETP = donnees_TD_ETP_elegant(nom_fichier_TD4) + DF_ETP = donnees_TD_ETP_2subplots(nom_fichier_TD4) + + print(DF_ETP.head(10)) +print("phase suivante, fichier binaire de lames d'eau radar") + +tracer_binaire = True + +# recherche du nom du fichier binaire +if Path.is_file(Path(nom_fichier_binaire)) and tracer_binaire: + print(f"nom_chemin_binaire1 : {nom_fichier_binaire} ") + + # vérification des dates + + # lecture des valeurs + # cf fonctions Chronique.lire_chronique Lecture_Patnthere...chronique + uint16_valeurs = None + with open(nom_fichier_binaire, 'rb') as fic_binaire: + try: + uint16_valeurs = np.fromfile(fic_binaire, dtype=np.uint16, count=int(len(liste_dates))) + statut_lecture = "OK" + + except: + statut_lecture = "erreur" + + # VERIF + print("Ensemble des valeurs lues avant traitement (lacunes, diviseur...) : ", set(uint16_valeurs)) + + if statut_lecture == "OK": + + # Traitement des lacunes + nb_lacunes = 0 + for valeur in uint16_valeurs: + if int(valeur) == int(CODE_LACUNE_BINAIRE): + nb_lacunes += 1 + print("Nombre de lacunes = ", nb_lacunes) + + # on travaille avec des LAMES D'EAU en centième de mm, à passer en mm + valeurs = np.array( + [entier / DIVISEUR if entier != int(CODE_LACUNE_BINAIRE) else np.nan for entier in + uint16_valeurs]) + + # tracé + # PlotLy + debut = datetime.now() + if trace_plt: + trace_avec_plt(liste_dates, valeurs) + # trace_avec_plt(liste_dates, valeurs, "stem") + # trace_avec_plt(liste_dates, valeurs, "hlines") + + # Pandas, dont DataShader + # préparation d'un DataFrame avec les données + + if trace_ds or trace_bok or trace_pd: + # toute la liste ou juste DEBUT FIN + # liste_date_pd = pd.DatetimeIndex(liste_dates, freq='infer') + + date_debut_pd = pd.to_datetime(date_premiere_valeur) + date_fin_pd = pd.to_datetime(date_premiere_valeur + (len_of_tvect - 1) * timedelta(minutes=PDT_OBS_EN_MIN)) + print("dates de début et fin", date_debut_pd, date_fin_pd) + + range_dates_pd_pour_index = pd.date_range(date_debut_pd, date_fin_pd, freq='5min') + + print(len(range_dates_pd_pour_index), len(valeurs), len_of_tvect) + + # les données doivent être dans un format DataFrame + # ts_lamedeau = pd.Series(valeurs, index=liste_date_pd) + ts_lamedeau = pd.Series(valeurs, index=range_dates_pd_pour_index) + + print(ts_lamedeau.head(10)) + print("Verification de l'analyse des dates : ", date_debut_pd, " mois ", date_debut_pd.month) + + if trace_pd: + # POUR DATAFRAMES + # cols = list(df_lamedeau) + # print(cols) + + tracer_DF_lamedeau_moyennes_mobiles(pd.DataFrame(ts_lamedeau)) + + # Deux courbes + debut = datetime.now() + ax1 = df_lamedeau.loc[:,cols[1]].plot (label=cols[1], title ="Avec pandas, 2 courbes", color='purple') + ax2 = ax1.twinx() + df_lamedeau.loc[:, cols[2]].plot(label=cols[1]) + + plt.show() + temps = datetime.now() - debut + print ("temps écoulé, Pandas 2 courbes (sans création DF):", temps) + + + # Une seule courbe + debut = datetime.now() + df_lamedeau.loc[:, cols[1]].plot(label=cols[1], title="Avec pandas", color='purple') + temps = datetime.now() - debut + plt.show() + + print("temps écoulé Pandas (sans création DF):", temps) + + + # MOYENNES PDT FIXE + # Resample + # https: // towardsdatascience.com / playing - with-time - series - data - in -python - 959e2485bff8 + + print("Cumuls; pdt fixes") + + # ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + # title="Avec pandas, données moyennées (pas de temps fixe)", + # color='purple') + + ts_mensuel = ts_lamedeau.resample('M').sum() + ts_journalier = ts_lamedeau.resample('D').sum() + print("trace_3_courbes_avec_pandas(ts_lamedeau, ts_mensuel, ts_journalier)") + trace_3_courbes_avec_pandas(ts_lamedeau, ts_mensuel, ts_journalier) + print("trace_3_courbes_avec_pandas_donc_vlines(ts_lamedeau, ts_mensuel, ts_journalier)") + trace_3_courbes_avec_pandas_donc_vlines(ts_lamedeau, ts_mensuel, ts_journalier) + + # barplots : une catastrophe + + #ax1 = df_lamedeau.loc[:, cols[1]].plot(label=cols[1], + # title="Avec pandas données moyennées (pas de temps fixe)", + # color='purple') + #ax2 = ax1.twinx() + + ax = df_mensuel.loc[:, cols[1]].plot(label=cols[1] + ' cumul mensuel', color='blue', kind='bar') + df_journalier.loc[:, cols[1]].plot(label=cols[1] + ' cumul journalier', color='orange', kind='bar') + # https: // stackoverflow.com / questions / 5902371 / matplotlib - bar - chart - with-dates + # ax.xaxis_date() + + plt.legend() + plt.show() + + + # =============================================================== + # plot_moyenne_mois_avec_rectangles + # trace_mensuel_avec_rectangles marche + print( + " on passe trace_mensuel_avec_rectangles(ts_lamedeau,ts_mensuel,ts_journalier,trace_rect_mensuels=True)") + if False: + trace_mensuel_avec_rectangles(ts_lamedeau, ts_mensuel, ts_journalier, trace_rect_mensuels=True) + + print("trace_mensuel_avec_hlines(ts_lamedeau, ts_mensuel, ts_journalier, trace_hlines=True)") + trace_mensuel_avec_hlines(ts_lamedeau, ts_mensuel, ts_journalier, trace_hlines=True) + print( + "HautBas_trace_mensuel_avec_rectangles(ts_lamedeau, ts_mensuel, ts_journalier, trace_rect_mensuels=True)") + HautBas_trace_mensuel_avec_rectangles(ts_lamedeau, ts_mensuel, ts_journalier, trace_rect_mensuels=True) + + print( + "HautBas_trace_mensuel_avec_hlines(ts_lamedeau, ts_mensuel, ts_journalier, trace_hlines_mensuels=True)") + + HautBas_trace_mensuel_avec_hlines(ts_lamedeau, ts_mensuel, ts_journalier, trace_hlines_mensuels=True) + + # =============================================================== + + # Marche pô, MemoryError même pour les mois ?... + print("et le dernier qui ne marche pas, pb avec collections et ax.add_collection avec un x en dates") + trace_bars_hack_rectangles(ts_lamedeau, ts_mensuel, ts_journalier, hack_rect_mensuels=True) + + # pause = input("on continue vers les jours ?") + + + # jours : memory error ? + + trace_rect_m = False + debut = datetime.now() + ax1 = ts_lamedeau.plot(label="lames d'eau à 5 min", + title="Avec rectangles corps du programme, moyennes journalières (pas de temps fixe)", + color='purple', zorder=10) + + ax2 = ax1.twinx() + date_debut_pd = ts_lamedeau.index[0] + date_fin_pd = ts_lamedeau.index[-1] + + ts_debutfin = pd.Series([ts_mensuel.mean(), ts_mensuel.mean()], index=[date_debut_pd, date_fin_pd]) + ts_debutfin.plot(ls=':', ax=ax2) + + # https://stackoverflow.com/questions/10550477/how-do-i-set-color-to-rectangle-in-matplotlib + color_list = [] + #patch_list = [] + for debut_rect, valeur in zip(ts_journalier.index, ts_journalier): + if debut_rect.month in [12,1,2]: + code_couleur = 'blue' + elif debut_rect.month in [3,4,5]: + code_couleur = 'pink' + elif debut_rect.month in [6,7,8]: + code_couleur = 'yellow' + else: + code_couleur = 'orange' + + #color_list.append(code_couleur) + + if trace_rect_m : + ax2.add_patch(Rectangle((debut_rect, 0.1), timedelta(days=30), valeur, color=code_couleur, alpha=0.8)) + + # print(debut_rect, valeur, code_couleur) + # patch = patches.Rectangle(xy, w, h, linewidth=1, edgecolor=edgecolor, facecolor=facecolor) + #patch_list.append(Rectangle((debut_rect, 0.1), timedelta(days=30), valeur)) + + #dates = [pd.to_datetime(datepd) for datepd in df_journalier.index] + + # tests différentes solutions + #ax2.vlines(df_journalier.index, 0, df_journalier["lames d'eau en mm"],color=color_list) + #ax2.stem(df_journalier.index, df_journalier["lames d'eau en mm"]) + + + notre_cmap = ListedColormap(color_list) + patches_collection = PatchCollection(patch_list, cmap=notre_cmap, alpha=1 ) + patches_collection.set_array(np.arange(len(patch_list))) + ax1.add_collection(patches_collection, zorder=5) + + max_valeur = max(ts_lamedeau.max(), ts_journalier.max()) + min_valeur = min(0, ts_lamedeau.min(), ts_journalier.min()) + ax1.set_ylim(0, ts_lamedeau.max() * 1.1) + ax2.set_ylim(0, ts_mensuel.max() * 1.1) + + temps = datetime.now() - debut + plt.show() + + print("temps écoulé Pandas, jours, avec vlines", temps) + + + # MOYENNES MOBILES + # Roll + + # DataShader + bokeh, interactif + if trace_bok: + print("DataShader interactif ? ") + # def create_image_une_serie(df, x_range, y_range, w=900, h=300, col_x="pdt", col_y="lames d'eau en mm", how='linear') + p = base_plot(t_bokeh, y_range) + print(t_bokeh, x_range, y_range) + + # # InteractiveImage rend p interactive en établissant un LIEN entre l'objet figure p et le callback défini + InteractiveImage(p, create_image_une_serie) + +"""