Contenu | Rechercher | Menus

Annonce

Ubuntu-fr vend de superbes t-shirts et de belles clés USB 32Go
Rendez-vous sur la boutique En Vente Libre

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 05/08/2019, à 07:44

BenjiBoy

Rose des vents // Windrose

Bonjour à tous,

dans le cadre de rendre accessibles et observables facilement les données des stations météo qu'on installe en complément de notre matos sur le terrain, j'aimerais créer une rose de vent.
C'est un type de graphique plus compréhensible pour l'affichage de l'orientation et la vitesse des vents enregistrés par une station météo.
J'ai regardé avec gnuplot que je commence à avoir pas mal l'habitude d'utiliser, mais c'est juste trop compliqué, et pas fait pour.
J'ai donc regardé avec python, que je ne maîtrise pas bien, et ça semble nettement plus simple.

Dans mes recherches je suis tombé sur cette page, qui est ce vers quoi je souhaite tendre.
Le graphe est précis, esthétique et lisible, et le programme est court.


Sauf que pour ici les données sont en "random" et j'aimerais bien savoir :
- Comment substituer la génération random par une table de données ?
- Quelle format doit avoir la table de données  (date | valeur vitesse | valeur direction ) ?


a+

Hors ligne

#2 Le 05/08/2019, à 07:56

BenjiBoy

Re : Rose des vents // Windrose

J'oubliais, pour répondre à la question 2, il vous faut un échantillon de données pour vous faire une idée, car bien sûr l'anémomètre est codé en degré, pas en point cardinal !

Datetime,RecNbr,AirTC_Avg,WS_ms_TMx,WS_ms_Max,flux_density_Std,WindDir,flux_density_Avg,WS_ms_Std,WS_ms_Avg,flux_density_Max,RH,flux_density_TMx,total_flux_Tot
2018-12-05 03:30:00,0,16.04,"(912828120, 0)",0.0,1.563,4.3,2.626,0.0,0.0,6.863,51.57,"(912828120, 0)",1.4182151556015015
2018-12-05 03:40:00,1,16.03,"(912828660, 0)",0.0,0.097,4.3,1.257,0.0,0.0,1.43,51.5,"(912828660, 0)",0.7541472911834717
2018-12-05 03:50:00,2,16.03,"(912829260, 0)",0.0,1.315,4.299,1.511,0.0,0.0,5.424,51.41,"(912829740, 0)",0.9064244627952576
2018-12-05 04:00:00,3,16.06,"(912829860, 0)",0.0,2.049,4.3,2.185,0.0,0.0,6.256,51.48,"(912829920, 0)",1.3107095956802368
2018-12-05 04:10:00,4,16.04,"(912830460, 0)",0.0,0.052,4.3,0.691,0.0,0.0,0.769,51.48,"(912830460, 0)",0.41474080085754395

Ce sont les labels "WindDir" et "WS_ms_Avg" qui nous intéressent.

Dernière modification par BenjiBoy (Le 05/08/2019, à 07:58)

Hors ligne

#3 Le 05/08/2019, à 11:03

kevlar

Re : Rose des vents // Windrose

Bonjour.
En ce qui concerne l'échantillon fourni, il s'agit à l'évidence de données "texte" (ASCII ou UTF8) rangées dans un fichier de type tableur, au format "CSV" (Comma separated value).
Dès lors, les données doivent être lues dans le fichier, par exemple ligne par ligne, et converties du format texte vers un format numérique. Je ne connais pas le Python, mais tous les langages ont ce type de fonction , transformant du texte brut en une valeur numérique.
Exemple dans ton échantillon : la colonne "airTc_Abg" c'est du texte "16.04" (notation US) qui doit être converti en une valeur flottante 16,04 (notation française).
Autre petit point : la colonne n°1, ce sont des données date+heure qui correspondent au format géré par la fonction "strftime" qui existe en C, et donc a son équivalent en Python.
Etc.
Mais pourquoi réinventer la roue ?
1- Pourquoi n'essayes-tu pas de le faire importer par ton tableur préféré sachant que c'est du CSV ?
Je pense que le diagramme polaire que tu demandes correspond à ce qui se nomme "radar" sous Excel (c'était le terme de l'époque, dans mes souvenirs, jamais utilisé sous LibreOffice, je ne sais pas s'il y a un équivalent).
2- Sachant que les données sont en CSV, moi je passerais par "R" (le package statistique) qui adore ce format, et je suis certain qu'il y a quelque part un package "météo" tout prêt pour produire ton diagramme polaire/radar...
3- si tu veux le programmer en Python, passe par les fonctions Cairo ; ton affichage a à faire avec les représentations circulaires (regarde "cairo_arc" + "pie chart" par exemple, recherche en anglais)
Bon courage.

Hors ligne

#4 Le 05/08/2019, à 11:04

kevlar

Re : Rose des vents // Windrose

Et j'en rajoute pour le tableur après avoir relu :
1- importer
2- dégager les colonnes autres que "WindDir" et "WS_ms_Avg"
3- représenter graphiquement ces deux-là.

Oeuf course, çà peut se faire "avec classe" sous R ...

Hors ligne

#5 Le 05/08/2019, à 12:28

melixgaro

Re : Rose des vents // Windrose

Bonjour,

Non, le séparateur décimal doit être un point pour que python comprenne. Il ne faut pas du tout transformer 16.04 en 16,04.

In [10]: float("16,04")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-10-e3f0c52fe679> in <module>()
----> 1 float("16,04")

ValueError: could not convert string to float: '16,04'

In [11]: float("16.04")
Out[11]: 16.04

Python sait très bien lire le csv, il suffit de charger le module csv ainsi en début de code :

import csv

Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#6 Le 05/08/2019, à 14:16

BenjiBoy

Re : Rose des vents // Windrose

Hello,
Merci pour vos indications, mais il me paraît nécessaire d'être un peu plus précis.

Déjà je décris rapidement la chaîne d'acquisition :
- Grandeur environnemental (température, vent, ...)
-> numérisation par le matériel d'acquisition
-> stockage local
-> Transfère par routeur 3G toutes les 10 minutes
-> Stockage sur serveur centralisé
-> Mise à disposition des données en ligne après vérification de la continuité.

L'ensemble est géré par des routines (des scripts bash lancés par crontab) pour valider automatiquement le fonctionnement de la station.

Et mon "TP" c'est d'en plus de cela automatiser la création d'un petit graphe journalier / hebdomadaire, type météo pour les gens habitants proche de nos installations.
A priori je vais partir sur une solution :
- rsync du fichier de données original sur un second secteur serveur (mon secteur bac-à-sable)
- awk sur les deux colonnes qui m'intéresse ("speed" et "azimuth") et création de deux fichiers speed.csv et azimuth.csv.
- Génération de la rose des vents (tous les X minute(s) / heure(s)) et push sur un FTP pour ensuite, pourquoi pas, l'intégrer dans un mini site web (ça, on verra).

Et donc sur le code qui suit :


import matplotlib.pyplot as plt
import numpy as np
theta = np.linspace(0,2*np.pi)
r = np.linspace(0,15,16)
Theta, R = np.meshgrid(theta, r)
C = np.sinc(Theta-3)+(5-np.sqrt(R))+np.random.rand(len(r),len(theta))
C = np.ma.masked_less_equal(C,2)
fig, ax = plt.subplots(subplot_kw={"projection":"polar"})
ax.pcolormesh(Theta, R, C, vmin=2, vmax=5)
plt.savefig('plot.png')

Il me semble qu'il faut que je remplace "C = np.sinc(Theta-3)+(5-np.sqrt(R))+np.random.rand(len(r),len(theta))" par la table de valeurs qui serait dans speed.csv et azimuth.csv.

Ca me paraît plus clair, mais comprenez-vous mieux là ou j'en suis et ce vers quoi je me dirige ?

a+

Hors ligne

#7 Le 05/08/2019, à 14:53

BenjiBoy

Re : Rose des vents // Windrose

Ooouuuuh alors il y a une version du graphe avec plotly encore plus sexy, mais alors j'ai rien compris à comment il génère ça.
Je vous donne la page de la doc.
Je suis sur le séant et dubitatif, un ensemble assez peu productif.

Précisions, celui-ci implique d'avoir le module plotly à jour.


a+

Hors ligne

#8 Le 05/08/2019, à 18:13

melixgaro

Re : Rose des vents // Windrose

Dans tous tes exemples, il semble que ce soit une rose des vents moyenne et non pas instantanée, c'est-à-dire qu'elle combine des mesures sur une certaine durée pour avoir une idée du comportement moyen. Est-ce bien ce que tu veux ?

Dans l'exemple sur stackoverflow, on voit en moyenne la direction la plus touchée par la pollution (NNW, avec un vent dont la vitesse est typiquement de 2 km/h, figure de la réponse validée). Dans l'exemple avec plotly, la première figure montre la direction, force et fréquence des vents. Tu vois aussi que pour cahque exemple, trois données sont représentées : une par l'angle formée avec l'axe horizontal, une par la distance au centre et une par la couleur. Et tu vois qu'il faut beaucoup de points de mesure (pas seulement 5 comme dans ton extrait - mais j'imagine que ça n'est pas un problème si ta station météo tourne en continue depuis un moment). Quelle est la troisième dimension que tu veux représenter ?


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#9 Le 06/08/2019, à 07:45

BenjiBoy

Re : Rose des vents // Windrose

Salut melixgaro,

oui tu as bien cerné le truc.
Effectivement il y a une notion de fréquence que je ne sais pas comment intégrer à mes mesures (dont j'ai effectivement livré un extrait de 5 lignes en guise d'échantillon sur beaucoup plus). Enfin disons que je vois mais ça va demander un peu de traitement de données.

Je galère avec plotly express, je ne comprends pas ce que c'est.
Dans le code

import plotly.express as px
wind = px.data.wind()
fig = px.bar_polar(wind, r="frequency", theta="direction", 
                   color="strength", template="plotly_dark",
                   color_discrete_sequence= px.colors.sequential.Plasma[-2::-1])
fig.show()

Je pense qu'il faut que je remplace "wind = px.data.wind()" par mes données, mais je ne comprends pas comment ça marche.
J'essaie de trouver de la documentation sur plotly express, mais c'est fou qu'il y ait si peu d'aide là-dessus.
Au moins bash il y a --help quand t'es paumé ... Là je panne plus rien.

PS : question con, python 2.7 suffit avec plotly 4.0 ?

Dernière modification par BenjiBoy (Le 06/08/2019, à 08:28)

Hors ligne

#10 Le 06/08/2019, à 09:02

BenjiBoy

Re : Rose des vents // Windrose

Je complète un peu.
Je dirais qu'il y a un problème de format.

Il y a donc la banque de données "test" fournie avec plotly, dans la commande "wind = px.data.wind()". Lorsque je la regarde sur python, j'ai ça :

>>> wind
    direction strength  frequency
0           N      0-1       0.50
1         NNE      0-1       0.60
2          NE      0-1       0.50
..        ...      ...        ...
125       WNW       6+       2.20
126        NW       6+       1.50
127       NNW       6+       0.20

[128 rows x 3 columns]

Ce qui est propre, et utilisable par python.

Et lorsque j'essaie de lire ma table de données à moi j'ai ça :

>>> lines
['WindDir\tWS_ms_Avg\n', '1.563\t0.0\n', '0.097\t0.0\n', '1.315\t0.0\n', '2.049\t0.0\n', '0.052\t0.0\n', '0.067\t0.0\n', '0.208\t0.0\n', '0.221\t0.0\n', '0.056\t0.0\n', '0.03\t0.0\n', '0.037\t0.0\n', '0.056\t0.0\n', '0.042\t0.0\n', '0.059\t0.0\n', '0.056\t0.0\n',
[...]
'2.75\t0.754\n', '5.394\t0.264\n', '9.05\t0.276\n', '15.34\t0.361\n', '8.0\t0.408\n', '44.86\t0.348\n', '17.41\t0.342\n', '38.24\t0.478\n']

Ce qui est dégueulasse, et probablement inbitable en l'état par python.

Hors ligne

#11 Le 06/08/2019, à 09:10

melixgaro

Re : Rose des vents // Windrose

Salut,

Rappel, python2.7 est en fin de vie (moins de 5 mois !) : https://pythonclock.org/

Essaye de charger ton fichier vidéo avec le module csv.


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#12 Le 06/08/2019, à 09:29

melixgaro

Re : Rose des vents // Windrose

Et donc, si je propose des trucs, ça sera en python3 wink


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#13 Le 06/08/2019, à 10:09

kevlar

Re : Rose des vents // Windrose

Bonour.
Pour le nettoyage, il faut simplement retire la première ligne d'en-tête du fichier "brut" en CSV. Je suis convaincu que çà existe dans la bibliothèque Python qui gère le CSV ? sinon çà se fait très simplement.
En tout cas, je suis ce projet avec intérêt, notamment pour la partie "mise sur le web" qui me donne des idées.
Bonne suite !

Hors ligne

#14 Le 06/08/2019, à 10:10

kevlar

Re : Rose des vents // Windrose

et pour les \n en fin de chaîne, partotu ailleurs, ce sont des "retours-chario" dont ke ne comprends pas la présence ; ici encore, en Python, vous avez la chance d'avoir des fonctions avancées de traitement de chaîne, ce sera donc facile à nettoyer !

Hors ligne

#15 Le 06/08/2019, à 10:16

melixgaro

Re : Rose des vents // Windrose

Il y a des caractères \n car BenjiBoy a dû faire ce qu'il annonçait, càd extraire les deux colonnes qui l'intéresse dans deux fichiers différents d'une colonne. Fichiers qu'il a lu comme du simple texte. Tout ça me paraît maladroit (tu pourras arriver à tes fins quand même, hein) car avec le module csv tu peux lire le fichier en entier puis travailler sur les colonnes utiles. Ça évite des pré-traitements avec awk ou autre.


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#16 Le 07/08/2019, à 14:41

BenjiBoy

Re : Rose des vents // Windrose

Hello,

alors en fait après discussion avec un collègue de mon labo, il va falloir faire un peu de "binning" et "bucketing"...
Car les données brutes récupérées sont précises mais la rose de vent est un graphe statistique qui catégorise les données par secteur en 3D (intensité, azimuth, fréquence).

Donc je vais devoir faire en sorte de créé un tableau à partir des données. Ca va demander n peu de temps ... Comme àça ne fait pas parti de mes tâches prioritaire en ce moment, je le ferai un peu au fur et à mesure.

Dès que j'ai un truc qui ressemble à quelque chose, je viens faire part de mes avancées ici.

a+ !

Hors ligne

#17 Le 08/08/2019, à 10:13

BenjiBoy

Re : Rose des vents // Windrose

Hello,

et bien j'arrive à avoir quelque chose d'intéressant. Concernant le binning hein, j'ai pas encore pondu la rose, si je puis dire.

Voici toute la démarche, depuis les données, jusqu'à l'obtention d'un set utilisable pour une WindRose de plotly 4.

Donc je pars d'une table de connées brute comme ceci (c'est du Campbell pour ceux qui connaissent):

Datetime,RecNbr,AirTC_Avg,WS_ms_TMx,WS_ms_Max,flux_density_Std,WindDir,flux_density_Avg,WS_ms_Std,WS_ms_Avg,flux_density_Max,RH,flux_density_TMx,total_flux_Tot
2018-12-05 03:30:00,0,16.04,"(912828120, 0)",0.0,1.563,4.3,2.626,0.0,0.0,6.863,51.57,"(912828120, 0)",1.4182151556015015
2018-12-05 03:40:00,1,16.03,"(912828660, 0)",0.0,0.097,4.3,1.257,0.0,0.0,1.43,51.5,"(912828660, 0)",0.7541472911834717
2018-12-05 03:50:00,2,16.03,"(912829260, 0)",0.0,1.315,4.299,1.511,0.0,0.0,5.424,51.41,"(912829740, 0)",0.9064244627952576
2018-12-05 04:00:00,3,16.06,"(912829860, 0)",0.0,2.049,4.3,2.185,0.0,0.0,6.256,51.48,"(912829920, 0)",1.3107095956802368
2018-12-05 04:10:00,4,16.04,"(912830460, 0)",0.0,0.052,4.3,0.691,0.0,0.0,0.769,51.48,"(912830460, 0)",0.41474080085754395
[...]

Puis j'exerce un awk (parce que je sais pas encore comment faire dans python, mais ça viendra) :

awk -F "," '{print $6 "\t" $8}' ../meteo.csv > data.csv

ce qui transforme la table comme ceci :

flux_density_Std	flux_density_Avg
0.0	4.3
0.0	4.3
0.0	4.299
0.0	4.3
0.0	4.3
[...]

Note : du fait du format un peu spécifique des pics de vitesse du vent "(912828120, 0)", le awk saut une colonne dans le header. Du coup les headers "flux_density_Std    flux_density_Avg" ne sont pas ceux correspondants.
Enfin, j'applique ce code python :

import pandas as pd
data = pd.read_csv('data.csv', sep='\t')
data.columns = ['vitesse', 'azimut']
bins1 = [-1,0.28,1.39,2.78,5.56,8.33,13.89,27.78]
data['cat'] = pd.cut(data['vitesse'], bins1)
bins2 = [-1,45,90,135,180,225,270,315,360]
data['cardinal'] = pd.cut(data['azimut'], bins2)
paf=data.groupby('cardinal')['cat'].value_counts().sort_index()

Voilà ce que j'obtiens :

>>> paf
cardinal    cat           
(-1, 45]    (-1.0, 0.28]      4225
            (0.28, 1.39]       938
            (1.39, 2.78]       668
            (2.78, 5.56]       299
            (5.56, 8.33]       176
            (8.33, 13.89]      162
            (13.89, 27.78]       2
(45, 90]    (-1.0, 0.28]       198
            (0.28, 1.39]       710
            (1.39, 2.78]       826
            (2.78, 5.56]       651
[...]
(270, 315]  (-1.0, 0.28]        68
            (0.28, 1.39]      1119
            (1.39, 2.78]      1548
            (2.78, 5.56]       592
            (5.56, 8.33]        36
            (8.33, 13.89]       12
(315, 360]  (-1.0, 0.28]        32
            (0.28, 1.39]       431
            (1.39, 2.78]       353
            (2.78, 5.56]       134
            (5.56, 8.33]        38
            (8.33, 13.89]       23
            (13.89, 27.78]       1

Renote : les vitesses et azimuts commencent à -1 car je n'ai pour l'instant pas pris le temps de comprendre pourquoi lorsqu'on inscrit "0, le "0" est précisément exclu.
A noter que la station a beaucoup de "0.000" ce qui statistiquement est très rare, il faudra que je me penche sur la question plus tard.

Maintenant je "n'ai plus qu'à" faire en sorte que la génération du graphe utilise les bonnes lignes et colonnes, et ça devrait sortir.
Bon étant venu exceptionnellement tôt ce matin au taf, j'ai pris du temps là-dessus mais je vais vraiment devoir passer à autre chose pour le moment, donc pas d'inquiétude si ça ne bouge pas trop pendant quelques jours.


Bonne journée, à+

Hors ligne

#18 Le 19/08/2019, à 15:38

BenjiBoy

Re : Rose des vents // Windrose

Hello,

bon j'ai définitivement un problème qui se situe sur le binning.

Je pense que python me génère un dataframe, qui n'est pas enregistrable en tant que fichier de données "propre".
Lorsque je pars du "data" :

     vitesse  azimut            cat    cardinal
0      5.062  111.50   (2.78, 5.56]   (90, 135]
1      4.905  120.80   (2.78, 5.56]   (90, 135]
2      4.925  124.60   (2.78, 5.56]   (90, 135]
[...]
141    1.034  319.20   (0.28, 1.39]  (315, 360]
142    1.713  281.10   (1.39, 2.78]  (270, 315]

[143 rows x 4 columns]

Je veux arriver à quelques chose style :

cardinal    cat    nmbrs
(-1, 45]    (-1.0, 0.28]      4225
            (0.28, 1.39]       938
            (1.39, 2.78]       668
[...]
(315, 360]  (-1.0, 0.28]        32
            (0.28, 1.39]       431
            (1.39, 2.78]       353

[128 rows x 3 columns]

Hors j'arrive à ce que je mets plus haut, qui je pense n'est pas un truc traitable pour python.

Je sais pas si je suis clair, compte tenu que je pythonne rien du tout j'enfonce peut-être des portes ouvertes.

Frustrant.
Promis je vais prendre des cours de python, je perds certainement un temps prodigieux.

a+

Hors ligne

#19 Le 19/08/2019, à 22:40

melixgaro

Re : Rose des vents // Windrose

Salut,

J'aurais peut-être le temps d'y réfléchir en fin de semaine…


Linux depuis ~2007. Xubuntu seulement.

Hors ligne