|
|
|
|
|
## B) Atelier 1 : un graphique simple, avec un axe des x et un axe des y
|
|
|
|
|
|
### B1) découverte des instructions de base dans la console
|
|
|
En séance, on fera les premiers pas dans la console. Si vous préférez, ou si vous préférez garder une trace, vous pourrez créer un fichier *.py ou un notebook (attention aux petites différences).
|
|
|
|
|
|
#### Premier contact : variables et listes ; essayez
|
|
|
En python, on ne déclare pas les variables ; par contre, elles ont bien un type.
|
|
|
Python se débrouille pour comprendre ce que vous affectez à la variable et va assigner le bon type.
|
|
|
|
|
|
```python
|
|
|
a = 10 # assignation, sans préciser le type
|
|
|
type(a) # réponse = int (typage réalisé par Python en fonction de l'entrée)
|
|
|
```
|
|
|
Pour travailler avec une collection d'éléments, il existe plusieurs structures en Python.
|
|
|
On va utiliser dans un premier temps le **conteneur** le plus "basique", la **liste**.
|
|
|
```python
|
|
|
une_liste_vide = list() # on crée une _instance_ de la classe _liste_
|
|
|
une_autre_liste_vide = [] # les CROCHETS suffisent à signaler à Python que vous avez créé une liste
|
|
|
ma_liste = [1, 2, 5, 10, 50] # une liste, définie comme telle par ses CROCHETS, avec ses éléments
|
|
|
|
|
|
ma_liste[1] # une liste est INDEXABLE* ; le résultat peut vous surprendre : Python commence l'indexation à ZERO, eh oui
|
|
|
|
|
|
12 in ma_liste # quel est le type de la réponse renvoyée ?
|
|
|
ma_liste[2]= 12 # je peux changer un élément de la liste ; c'est possible car une liste est MUTABLE*
|
|
|
ma_liste.append(100) # j'ajoute un élément à la liste ; c'est possible car une liste est MUTABLE*
|
|
|
ma_liste_non_recommandee = [1, 2, 5, 10, "camembert" , 50.5, (8,12), ma_liste]
|
|
|
```
|
|
|
Le conteneur liste est un fourre-tout. Pour du calcul matriciel, on préférera la structure de numpy.array (objet array du module numpy).
|
|
|
On verra d'autres conteneurs par la suite : tuples et dictionnaires.
|
|
|
|
|
|
En Python, pas de 'begin" ni de 'end' ni d'accolades pour délimiter les blocs : on définit des **blocs de code** par la seule indentation : le bloc est annoncé par ":" et les lignes appartenant au bloc sont indentées de 4 espaces (ou une tabulation) par rapport à la ligne qui annonce le bloc.
|
|
|
C'est une habitude à prendre, et votre environnement de développement vous aidera beaucoup (sous PyCharm : no peut utiliser indifféremment 4 espaces ou une tabulation, et pour réajuster des blocs il y a Edit/Indent ou /Unindent).
|
|
|
```python
|
|
|
for element in ma_liste: # une liste est ITERABLE* ; tous les conteneurs sont itérables
|
|
|
print(element) # indentation de 4 espaces, on est dans le bloc de code
|
|
|
print("fini") # l'indentation a cessé, on a quitté le bloc
|
|
|
```
|
|
|
|
|
|
#### On en sait assez pour tracer !
|
|
|
On va utiliser le module pyplot de matplotlib ; il faut donc déclarer que l'on va l'utiliser, autrement dit on va l'**importer** d'abord.
|
|
|
L'usage est d'importer matplotlib.pyplot avec l'alias **"plt"** ; cela économise quelques frappes, et comme tout le monde fait comme ça vous pourrez plus facilement échanger du code.
|
|
|
|
|
|
```python
|
|
|
from matplotlib import pyplot as plt # instruction "canonique" !
|
|
|
plt.plot ( [1, 2, 5, 10, 50] , [11, 31, 53, 208, 502] ) # appel à fonction, arguments = une liste, une liste
|
|
|
plt.show() # à part dans JupyterLab, vous avez besoin de cette ligne pour afficher le graphique
|
|
|
```
|
|
|
[le graphique obtenu avec ces trois lignes de code](https://gitlab.irstea.fr/christine.poulard/atelier-matplotlib/-/blob/master/illustrations/Fig1_graphique_basique.png)
|
|
|
|
|
|
|
|
|
### une figure un peu plus habillée
|
|
|
**Références** : la Doc de matplotlib, très complète, ou des tutos comme [Python Simple](http://www.python-simple.com/python-matplotlib/pyplot.php)
|
|
|
|
|
|
On a déjà importé précédemment le module pyplot, donc il est "connu" pour tout le reste de la séance.
|
|
|
Vous avez ci-dessous les principales instructions, vous pouvez les manipuler et modifier le graphique comme vous le souhaitez.
|
|
|
|
|
|
A noter que l'on peut utiliser indifféremment pour certains arguments des noms en version longue ou courte :
|
|
|
lw = linewidth
|
|
|
ls = linestyle
|
|
|
c = color
|
|
|
|
|
|
```python
|
|
|
plt.plot ( [1, 2, 5, 10, 50] , [11, 21, 53, 108, 502], label="âge du capitaine", lw=2, marker='*', color='purple', ls=':' )
|
|
|
plt.xlabel('en unités du système international', color = 'green', fontsize = 14)
|
|
|
plt.ylabel('fois dix plus du bruit', color = 'blue', fontsize = 14)
|
|
|
plt.set_ylim(0, 800)
|
|
|
plt.title("ma première figure", fontsize = 14, horizontalalignment = 'left', loc = 'left')
|
|
|
plt.savefig("mafigure.svg") # l'extension suffit pour que Python comprenne quel format vous attendez
|
|
|
plt.savefig("mafigure.png")
|
|
|
plt.show() # pour faire apparaître le graphique
|
|
|
```
|
|
|
|
|
|
### Cas d'une abscisse temporelle - interactivité
|
|
|
En hydrologie, mais aussi en hydraulique, on manipule des chroniques, valeur=f(t).
|
|
|
Le module **datetime** est plutôt bien fait et vous rendra beaucoup de services.
|
|
|
Pour en savoir plus, voir diapos ou [page dédiée datetime](infos_datetime).
|
|
|
|
|
|
DU module datetime, on va beaucoup utiliser datetime ; pensez que c'est une classe (même s'il n'y pas de majuscule...) ; on définit une instance avec des arguments entiers
|
|
|
```python
|
|
|
from datetime import datetime, timedelta # module de gestion de dates "standard"
|
|
|
print (datetime.now())
|
|
|
date_de_creation_inrae = datetime(2020,1,1) # arguments= année, mois, jour ;
|
|
|
```
|
|
|
attention, datetime(2020,01,01) cause une erreur (je me fais avoir régulièrement...).
|
|
|
Cette instance a des attributs:
|
|
|
|
|
|
```python
|
|
|
date_de_creation_inrae.month
|
|
|
```
|
|
|
On a importé aussi timedelta, qui correspond à un "delta entre dates", donc une durée.
|
|
|
```python
|
|
|
duree_d_existence = datetime.now() - date_de_creation_inrae # différence entre deux dates
|
|
|
type(duree_d_existence) # type attendu = timedelta
|
|
|
un_jour = timedelta(days=1) # définir une durée directement
|
|
|
```
|
|
|
|
|
|
Attention, on ne peut pas écrire _timedelta(months=1)_ car un mois n'est pas une "durée" définie, cela dépend du mois...
|
|
|
|
|
|
# on va créer une longue chronique temporelle tirée du chapeau
|
|
|
# on définit une date de début, une date de fin (aujourd'hui) et on calcule le nombre de jours
|
|
|
|
|
|
```python
|
|
|
date_premiere_mesure = datetime(1806,1,1) # première date de la série temporelle de débit à Dresde
|
|
|
nombre_de_jours = ( datetime.now() - date_premiere_mesure ).days # propriété days du type timedelta
|
|
|
```
|
|
|
On va rejouer avec une boucle _for_, et découvrir une manière plus performante de créer une nouvelle liste avec une boucle.
|
|
|
On va créer une liste avec tous les jours depuis 1806
|
|
|
|
|
|
```python
|
|
|
# première manière de faire
|
|
|
etendue_temporelle = [] # ou = list() : je crée une liste vide
|
|
|
for i_jour in range(nombre_de_jours ) : #range(N) = boucle de 0 à N, N non inclus
|
|
|
etendue_temporelle.append(date_premiere_mesure + timedelta(days=i_jour) # ajout d'un terme à la liste vide
|
|
|
```
|
|
|
PyCharm vous permet de passer facilement d'une formulation à l'autre, ce qui est bien pratique au début (surtout en présence de _if_ et _else_, mais ceci est une autre histoire...
|
|
|
|
|
|
```python
|
|
|
# écriture équivalente en mode plus "compact" et efficace qu'une boucle for (on s'y fait et on y prend goût)
|
|
|
etendue_temporelle = [date_premiere_mesure + timedelta(days=i_jour) for i_jour in range(nombre_de_jours )]
|
|
|
numeros_de_mois = [date.month for date in etendue_temporelle ]
|
|
|
```
|
|
|
Et maintenant on peut tracer les numéros de mois en fonction de la date. Attention, vous allez être déçus par le résultat...
|
|
|
```python
|
|
|
plt.plot(etendue_temporelle , numeros_de_mois )
|
|
|
plt.ylabel('numéro de mois', color = 'blue', fontsize = 14)
|
|
|
plt.show() # est-ce vraiment juste un rectangle bleu ???
|
|
|
```
|
|
|
Si c'est tout bleu c'est normal : en fait l'information est trop dense, on n'y voit rien. Dans la barre du bas, avec l'icône "loupe" vous pouvez zoomer et dézoomer.
|
|
|
Cet outil, avec l'outil "glisser-déplacer", est bien pratique pour explorer une longue chronique, mais au passage on identifie des imperfections : les étiquettes de dates affichées ne sont pas forcément optimales ; on verra par la suite des solutions pour améliorer l'affichage.
|
|
|
On verra aussi à la fin comment ajuster la résolution d'affichage.
|
|
|
|
|
|
Nous avons réalisé des tests avec des données "tirées du chapeau", dans la suite on va aller lire des données dans des fichiers, [B2) lire un fichier texte et extraire l'information](AtelierB1_) |
|
|
\ No newline at end of file |