|
|
## B) Atelier 1 : un graphique simple, avec un axe des x et un axe des y
|
|
|
|
|
|
Maintenant que l'on a quelques clés pour tracer un graphique, on va se placer dans un cas fréquent : on a un fichier et on souhaite visualiser les données.
|
|
|
De toutes façons, il faut savoir lire les données dans un fichier, donc c'est l'occasion de voir comment se débrouiller en Python.
|
|
|
|
|
|
### B2) lire un fichier texte et extraire l'information
|
|
|
|
|
|
Vous trouverez du code déjà écrit dans le fichier Python visu_chronique.py, avec la fonction lecture_qj0_to_ts écrite pour lire des fichiers de débit journalier dans un des formats de la base Hydro2.
|
|
|
Vous êtes invités à vous approprier ce code, vous pouvez tester les instructions dans la console comme on a fait précédemment, et essayer de réécrire votre propre fonction.
|
|
|
|
|
|
Il existe des méthodes performantes pour lire des fichiers structurés (colonnes nommées et lignes), notamment dans pandas et seaborn (read_csv). Ici, le fichier à un format qui se prête moyennement bien aux lectures en bloc, et on va donc travailler à l'ancienne.
|
|
|
Au passage, on va manipuler plusieurs notions utiles de Python. .
|
|
|
|
|
|
#### a) Définir un nom de fichier et lire ce fichier
|
|
|
Pratique recommandée pour ouvrir un fichier : "with open(nom_fichier, 'r') as alias_du_fichier"
|
|
|
=> notion de "context manager" qui garantit que le fichier se fermera à la fin du bloc d'instructions, quoi qu'il arrive
|
|
|
Pour mieux comprendre les instructions de "découpage" des lignes (split) et leur transcription en dates et valeurs, manipulez dans la console la chaîne " QJO;B2220010;19680627;7330.000;C;9;"
|
|
|
|
|
|
``` python
|
|
|
ligne_lue_dans_le_fichier = "QJO;B2220010;19680627;7330.000;C;9;"
|
|
|
```
|
|
|
|
|
|
Si besoin, on fera un topo sur les dictionnaires, un type de conteneur central en python.
|
|
|
|
|
|
Une fois la fonction écrite, il faut l'exécuter avec un chemin comme argument.
|
|
|
|
|
|
Plusieurs solutions :
|
|
|
1) je tape le chemin en clair dans le code, avec des slash / et pas de backslash :
|
|
|
ts = lecteur_qj0_to_ts("C:/WorkSpace/2020-BaO_MultiDSpa/Migrateurs/Meuse/B2220010_qj_hydro2_2019.txt")
|
|
|
éventuellement :
|
|
|
chemin_complet = "C:/WorkSpace/2020-BaO_MultiDSpa/Migrateurs/Meuse/B2220010_qj_hydro2_2019.txt"
|
|
|
ts = lecteur_qj0_to_ts(chemin_complet)
|
|
|
2) je demande à l'utilisateur de saisir le nom au clavier
|
|
|
chemin_complet= input("Entrez le chemin complet vers le fichier de données")
|
|
|
# j'ai intérêt à vérifier si le fichier existe
|
|
|
from pathlib import Path
|
|
|
# explication : j'utilise la méthode is_file de Path sur l'objet nom_fichier converti en Path
|
|
|
if Path.is_file(Path(chemin_complet)):
|
|
|
ts = lecteur_qj0_to_ts(chemin_complet)
|
|
|
else:
|
|
|
print("chemine ", chemin_complet, " non valide")
|
|
|
3) j'utilise une fonction de Tkinter
|
|
|
from tkinter.filedialog import askopenfilename
|
|
|
|
|
|
chemin_complet= askopenfilename() # ouverture d'une fenêtre explorateur
|
|
|
|
|
|
=> figure selon 2 modalités, une fois à partir de listes issues d'un dictionnaire, et une autre fois avec le wrapper de pandas (mon_objet_pandas.plot)
|
|
|
|
|
|
b) Extraire l'information utile : "parser" les lignes
|
|
|
|
|
|
Ceci est un parsing "à l'ancienne", ligne par ligne. Un peu pénible, certes, cette étape permet de réaliser des vérifications et de décomposer des éléments, ainsi que de manipuler des notions de liste et string.
|
|
|
Pour une lecture "en bloc", avec des données bien structurées, voir les instructions modernes de type "read_csv" (du module pandas ou seaborn par exempe).
|
|
|
|
|
|
Les commentaires du code + la diapo doivent vous guider.
|
|
|
Pour comprendre, définissez une chaîne de caractères (string) nommée ligne dans la console
|
|
|
ligne = "QJO;B2220010;19680705;5280.000;C;9;"
|
|
|
# Effectuez ensuite des tests, par exemple :
|
|
|
"QJO" in ligne #retourne un boléen, vrai/faux (en Python, True.False, avec une majuscule)
|
|
|
ligne.splitee = ligne.split(";") # ligne_splitee est une LISTE de STRINGS
|
|
|
ligne.splitee[1] # élément d'indice 1, est-ce le premier ???
|
|
|
ligne.splitee[2][0:4] # string composé des caractères d'indices 0 à 4 EXCLU de l'élément d'indice 2
|
|
|
valeur_numerique = float(ligne.splitee[3] )
|
|
|
|
|
|
# Création d'un dictionnaire
|
|
|
|
|
|
# définition d'un dictionnaire ; entre accolades
|
|
|
dictionnaire_main = {1:"un", 2:"deux", 3: "trois", 4:"quatre", 5: "cinq"} # dictionnaire avec couples clé: valeur
|
|
|
mon_dictionnaire = dict() # dictionnaire vide
|
|
|
mon_dictionnaire [clef] = valeur # j'ajoute une entrée (j'ajoute des entrées comme je veux)
|
|
|
# la variable clef doit être d'un type NON-MUTABLE (voir notes) ; les types string, datetime, chiffre... conviennent
|
|
|
# la variable valeur peut être de n'importe quel type, y compris des conteneurs
|
|
|
mon_dictionnaire[clef] #renvoie la valeur
|
|
|
mon_dictionnaire.keys() # vue des clés ; ce n'est pas une liste mais c'est un itérable
|
|
|
for clef in mon_dictionnaire.keys() :
|
|
|
print("clé = ", clef, " valeur = ", mon_dictionnaire[clef])
|
|
|
# équivalent à
|
|
|
for clef in mon_dictionnaire:
|
|
|
print("clé = ", clef)
|
|
|
cle_de_sol in mon_dictionnaire.keys() # booléen, vrai si cle_de_sol est une ces clés
|
|
|
mon_dictionnaire.values() # vue des valeurs ; ce n'est pas une liste mais c'est un itérable
|
|
|
mon_dictionnaire.items() # vue des couples (clé, valeur) ; c'est un iterable dont les éléments sont des tuples
|
|
|
for clef, valeur in mon_dictionnaire.items() :
|
|
|
print("clé = ", clef, " et valeur = ", valeur)
|
|
|
|
|
|
# tracé à partir du dictionnaire, puis à partir d'une structure pandas Series
|
|
|
Ensuite, on compare 2 manière de tracer le graphique q(t) :
|
|
|
|
|
|
plt.plot(liste_des_dates, liste_des_q), avec liste_des_dates = clés du dictionnaire et liste_des_a = valeurs
|
|
|
|
|
|
on convertit le dictionnaire en objet pandas Series et on applique la méthode plot : ma_series.plot()
|
|
|
|
|
|
On introduit dans ce 2e cas un type de courbe "en créneaux" qui convient mieux à des valeurs moyennes journalières.
|
|
|
|
|
|
Comment exécuter la fonction ?
|
|
|
Deux solutions :
|
|
|
1) écrire les instructions dans le "corps du programme", précédé ici d'un test pour activer certaines sous-parties au fur et à mesure du déroulé
|
|
|
2) travailler dans la console et utiliser le fichier comme un module :
|
|
|
from Atelier_MatPlotLib_2021_part1 import lecteur_qj0_to_ts
|
|
|
from datetime import datetime, timedelta
|
|
|
from tkinter.filedialog import askopenfilename
|
|
|
import matplotlib.pyplot as plt
|
|
|
chemin_complet = askopenfilename()
|
|
|
ts = lecteur_qj0_to_ts(chemin_complet)
|
|
|
|