Nébulosité totale par région

Affichage de la nébulosité totale par région (tkinter) #

La nébulosité mesure l’opacité de la couverture nuageuse. Les données relatives à la nébulosité pour la France sont disponibles dans le cadre de la campagne opendata. Ainsi, sur cette page : donneespubliques.meteofrance.fr nous pouvons récupérer des fichiers contenant les relevés météo par mois pour un ensemble de villes de France (ou plutôt des stations).

Les données disponibles pour 2015 ont déjà été récupérées et concaténées dans un gros fichier que vous pouvez trouver ici : data_meteo_synop_2015.csv.gz. Une fois décompressé, le fichier est au format csv et le contenu des champs est détaillé ici : donneespubliques.meteofrance.fr (vous devez regarder dans cette doc pour savoir quel champ correspond à la nébulosité totale).

L’objectif de ce travail est de créer un programme, avec interface graphique, qui permet à l’utilisateur de saisir un code de station (par exemple 07335 pour Poitiers) et donne la valeur moyenne et la variance de la nébulosité sur l’année en ce lieu. Une courbe, représentant la nébulosité moyenne par mois (12 points donc) sera aussi tracée.

Pour parvenir à vos fins, vous aurez à :

  • lire un fichier csv depuis Python et le pré-traiter pour accéder facilement aux données
  • manipuler des dates (classe datetime.datetime)
  • créer l’interface graphique (elle contiendra labels, champs, boutons et courbes)

Partie non graphique #

Lecture d’un fichier csv #

Le format csv est un format texte (ouvrez le fichier pour voir ce qu’il contient). Il est donc possible de le traiter en utilisant les fonctions standard sur les chaînes. Il y a toutefois un module python csv qui simplifie un peu la tâche.

import csv
with open('nomfichier.csv', 'r') as csvfile:
    csvdata = csv.reader(csvfile, delimiter=';')
    for ligne in csvdata:
        print(ligne)

L’exemple précédent ouvre un fichier et l’affiche ligne par ligne. À chaque tour de boucle, la variable ligne est une liste contenant chacun de champs de la ligne traitée. Plutôt que de les afficher, il faut traiter ces données.

Dans un premier temps, adaptez cet exemple à votre cas, et vérifiez que tout fonctionne. Attention, le fichier est trop long pour être affiché entièrement. {%% /hint %}}

Traitement du fichier #

Une possibilité pour manipuler facilement les données par la suite est de construire un dictionnaire contenant les codes des stations comme clé. Chaque valeur du dictionnaire sera une liste. Chaque élément de la liste sera une mesure. Chaque mesure sera un tuple contenant en première position un timestamp (horodatage) et la valeur de la nébulosité totale.

Le fichier contient un horodatage dans un format qui ne vous échappera pas (première colonne). Cette donnée doit être transformée en un objet datetime qui sera plus facile à manipuler. Pour cela, regardez l’aide de la fonction datetime.datetime.strptime qui permet de transformer une chaîne contenant une date dans n’importe quelle format en datetime Python.

Certaines données sont parfois absentes (il est indiqué mq). Repérez les, et ignorez les simplement (il manquera donc certaines plages horaires dans la structure de données finale).

La structure de données que vous obtiendrez devra s’appeler alldata et ressembler à ceci :

{'07005': [(datetime.datetime(2015, 1, 1, 6, 0), 0),
            (datetime.datetime(2015, 1, 1, 9, 0), 25),
            (datetime.datetime(2015, 1, 1, 12, 0), 90),
            (datetime.datetime(2015, 1, 1, 15, 0), 90),
            (datetime.datetime(2015, 1, 2, 6, 0), 100),
            (datetime.datetime(2015, 1, 2, 9, 0), 100),
            (datetime.datetime(2015, 1, 2, 12, 0), 90),
            (datetime.datetime(2015, 1, 3, 6, 0), 100),
            (datetime.datetime(2015, 1, 3, 9, 0), 100),
            (datetime.datetime(2015, 1, 3, 12, 0), 100),
            (datetime.datetime(2015, 1, 4, 6, 0), 100),
            (datetime.datetime(2015, 1, 4, 9, 0), 90),
            (datetime.datetime(2015, 1, 4, 12, 0), 50),
            (datetime.datetime(2015, 1, 5, 6, 0), 60),
            ...],
    '07335' : ....
}

Le fichier de données contient plus de 150000 lignes, et le traitement peut mettre un peu de temps (moins d’une minute tout de même). {%% /hint %}}

Réalisez le code qui lit le fichier et crée la structure de données demandée. Faites valider cette étape par l’encadrant

Vous devez avoir exactement ce qui est demandé, c’est à dire un dictionnaire, contenant comme clé la station météo (sous forme d’une chaîne), et comme valeur une liste de tuples. Le premier élément du tuple sera le moment d’observation (type datetime) et le second élément sera un nombre (et non une chaîne) contenant l’observation. {%% /hint %}}

Vérifiez dans un premier temps que vous avez le bon nombre d’enregistrements :

>>> len(alldata['07335'])
2102

>>> len(alldata['07005']) 1272

{%% /hint %}}

Premier tracé de graphe #

Matplotlib permet de tracer toutes sortes de graphiques. Jetez un œil à la documentation :

Voici un exemple très simple qui trace une sinusoïde :

# import matplotlib                   # Pb avec matplolib 1.5.3
# matplotlib.use('TkAgg')             # Pb avec matplolib 1.5.3
from matplotlib import pyplot as plt
import math

pas = 0.1 x = [0.1 * i for i in range(50)] y = [math.sin(x_) for x_ in x] plt.plot(x, y) plt.show()

L’important à retenir est que nous devons fournir la liste des abscisses et la listes des ordonnées. Par chance, matplotlib accepte tout à fait les objets de type datetime en abscisse.

Tracez la courbe de la nébulosité au cours du temps pour Poitiers. Vous devez avoir environ 2000 points (sur les 3000 de l’année car il y a des données manquantes). {%% /hint %}}

Les données sont assez «bruitées» et cette courbe n’est pas très expressive…

Moyennes par mois #

Nous allons écrire une fonction qui prend en paramètre les mesures sur l’année et renvoie une liste de 12 valeurs, qui sont des moyennes mensuelles. Notez que l’attribut month de la classe datetime peut être très pratique pour ça :

> poitiers = alldata['07335']
> date_init = poitiers[0][0] # Première date
> print(date_init)
datetime.datetime(2015, 1, 1, 6, 0)
> print(date_init.month)
1 # Pour janvier

À la fin, vous devez avoir une liste du type :

[ 90, 70, .....]
    ^   ^
    |   |_ valeur pour février
    |_valeur pour janvier

Le premier élément d’une liste est l’élément 0, alors que janvier est le mois 1. Vous pouvez gérer ce petit problème comme bon vous semble.

Réalisez la fonction qui prend en paramètre la liste des mesures pour une station donnée et renvoie la liste des moyennes mensuelles {%% /hint %}}

Tracé des moyennes #

À présent, essayez de comparer les moyennes mensuelles pour deux villes bien choisies en traçant un graphique avec Matplotlib.

Faites valider cette étape par l’encadrant

Vous devez être capable de produire la courbe des moyennes pour 2 villes, et d’exécuter, dans le shell, la fonction de calcul de la moyenne : on envoie à cette fonction une liste comme alldata['07335'] et on récupère une liste de 12 valeurs, les moyennes mensuelles.

>>> moyennes_mensuelles(all_data['07335'])
[87.36150234741784,
 80.75722543352602,
 79.89690721649484,
 69.03030303030303,
 74.91071428571429,
 64.15584415584415,
 71.1875,
 71.91176470588235,
 63.075949367088604,
 78.10497237569061,
 83.54871794871795,
 73.91228070175438]

{%% /hint %}}

Vous devez rendre ce premier programme. {%% /hint %}}

{%% /hint %}}

Interface graphique #

On propose de faire une interface graphique qui ressemble à ceci :

Pour l’utiliser, on entre un nom de station, puis on clique sur afficher. Le graphe des moyennes mensuelles se met alors à jour, ainsi que la moyenne annuelle. Faites en sorte que le graphique se mette aussi à jour si on valide avec Entrée la saisie du numéro de station.

Pour intégrer un graphique dans une interface tkinter, consultez la FAQ Tkinter sur ce site.

Remarques #

Dans une utilisation réelle, il faut disposer d’un maillage géographique un peu plus fin, et surtout de plusieurs années de mesure. On peut estimer que des moyennes sur les 10 dernières années donnent un résultat plus intéressant que 2015 seule.

Une amélioration possible est d’utiliser le fichier contenant la liste des stations pour proposer une liste déroulante plutôt que devoir entrer le code de la station.

Réalisez l’interface en question, avec les améliorations que vous aurez le temps de faire, et faites valider cette étape par l’encadrant.

Vous devrez rendre votre fichier.

Votre programme doit s’exécuter directement en le démarrant dans un nouveau shell (Ctrl+Shift+E avec Pyzo), lorsqu’on entre le numéro de la station, la courbe annuelle doit s’afficher. {%% /hint %}} {%% /hint %}}