2 # -*- coding: utf-8 -*-
3 from configuration
import CONFIG
4 import gestionOMS
as oms
5 import gestion_unites
as u
6 from gestion_donnees
import calcule_max_graphique
, convertit_jours_vers_python
7 from gestion_erreurs
import debug
, erreur
, warning
8 from numpy
import arange
10 import matplotlib
.pyplot
as plt
12 # Essentiellement, la fonction qui trace la courbe
15 def cree_figure(conf
,l_jours
,l_poids
,typedonnee
,liste_err
):
16 """ conf est le dictionnaire de config. l_jours et l_poids les listes des temps (en jours) et de données
17 (donc pas forcément du poids)
18 typedonnee est le type de données (voir CONFIG["liste_typedonnees"]
19 liste_err la liste des erreurs à compléter (voir gestion_erreurs))
20 Renvoie la figure tracée"""
21 debug("debut de cree_figure. Config : "+str(conf
),liste_err
)
23 liste_data_labels_p
,liste_data_labels_z
= oms
.renvoie_liste_labels(conf
,CONFIG
["liste_data_choisie_p"],CONFIG
["liste_data_choisie_z"],liste_err
)
25 erreur("bug avec liste data labels",liste_err
)
28 ######################## Gestion des bornes #############################
29 # y a-t-il un maxi saisi par l'utilisateur ?
31 # Est-ce qu'on a donné un maxi quand même (car même échelle) ?
32 if conf
["non_sauve"].get("maxi",0) == 0:
33 jour_maxi
= calcule_max_graphique(l_jours
)
35 jour_maxi
= conf
["non_sauve"]["maxi"]+1
37 jour_maxi
= conf
["maxi"]+1
39 # On s'assure que c'est bien compris dans les bornes
40 jour_maxi
= max(CONFIG
["jours_mini_courbe"],min(jour_maxi
,CONFIG
["jours_maxi_courbe"]))
41 debug("cree_figure : gestion du jour max : "+str(jour_maxi
),liste_err
)
43 ##################### Gestion des unités ###############################
44 # si l'unité n'est pas précisée, ni en "non sauvé" ni par l'utilisateur
45 if conf
["unite"] == "" and conf
["non_sauve"].get("unite","") == "":
46 unite
= u
.choix_unite(jour_maxi
)
47 debug("Unité non précisée, on choisit "+unite
,liste_err
)
48 elif conf
["unite"] != "":
51 unite
= conf
["non_sauve"]["unite"]
53 ##################### Gestion de la prématurité #######################"
54 prema
= int(convertit_jours_vers_python(conf
["prematurite"],liste_err
))
55 ## Gestion des prémas, deux cas :
56 # Si agecorrige est oui, alors on veut juste soustraire la valeur de préma
57 # à toutes les données.
58 # Si agecorrige est non, alors on veut ajouter la valeur de préma aux courbes de référence.
59 debug("Prématurité : "+str(prema
)+" age corrigé : "+conf
["agecorrige"],liste_err
)
60 if prema
>0 and conf
["agecorrige"] == "oui":
61 l_jours
= [j
-prema
for j
in l_jours
]
62 jour_maxi
= jour_maxi
- prema
65 ###################### Conversion des unités ###########################""
66 l_jours_conv
= u
.convertit_tableau(l_jours
,unite
,liste_err
)
67 # Attention, comme les jours commencent à partir de 0, faut enlever 1 pour avoir la borne...
68 age_maxi
= u
.convertitunite(jour_maxi
-1,unite
,liste_err
)
70 debug("cree_figure : conversion des unités ok : "+str(l_jours_conv
),liste_err
)
72 #####################" Courbes OMS et titre ######################################"
73 titre
= "Courbe de "+typedonnee
+" OMS"
74 if conf
["typecourbe"] == "P":
76 liste_data_labels
= liste_data_labels_p
77 if conf
["sexe"] == "M":
78 fichier_oms
= CONFIG
["fichiersOMS"][typedonnee
]["perc_garcon"]#f_poids_perc_garcon
79 titre
+= " (percentiles, garçon)"
80 elif conf
["sexe"] == "F":
81 fichier_oms
= CONFIG
["fichiersOMS"][typedonnee
]["perc_fille"]
82 titre
+= " (percentiles, fille)"
84 fichier_oms
= CONFIG
["fichiersOMS"][typedonnee
]["perc_mixte"]
85 titre
+= " (percentiles)"
86 elif conf
["typecourbe"] == "Z":
87 liste_data_labels
= liste_data_labels_z
88 if conf
["sexe"] == "M":
89 fichier_oms
= CONFIG
["fichiersOMS"][typedonnee
]["z_garcon"]
90 titre
+= " (moyenne et écarts-types, garçon)"
91 elif conf
["sexe"] == "F":
92 fichier_oms
= CONFIG
["fichiersOMS"][typedonnee
]["z_fille"]
93 titre
+= " (moyenne et écarts-types, fille)"
95 fichier_oms
= CONFIG
["fichiersOMS"][typedonnee
]["z_mixte"]
96 titre
+= " (moyenne et écarts-types)"
98 erreur("Type de courbe invalide"+conf
["typecourbe"],liste_err
)
101 # Si y'a un nom on met "courbe de machin"
103 titre
+= " de " +conf
["nom"]
106 titre
+= ", préma de "+conf
["prematurite"]
107 if conf
["agecorrige"] == "oui":
108 titre
+=" (courbe en âge corrigé)"
110 titre
+=" (courbe en âge réel, données OMS décalées)"
112 #debug("cree_figure : géré le type de courbe ok. Liste des data labels : "+str(liste_data_labels),liste_err)
113 debug("Fichier d'où extraire les données : "+fichier_oms
,liste_err
)
116 #### On extrait les données des courbes, et on convertit les jours dans l'unité voulues
118 t
= oms
.lire_fichier_csv(fichier_oms
)
120 erreur("cree_figure : Impossible d'ouvrir le fichier "+fichier_oms
, liste_err
)
123 debug("cree_figure : Conversion des données OMS à la bonne unité",liste_err
)
125 coljour
= (oms
.extraire_colonne(t
,0,jour_maxi
))
126 if prema
>0 and conf
["agecorrige"] != "oui":
127 coljour
= [j
+ prema
for j
in coljour
]
128 coljour
= u
.convertit_tableau(coljour
,unite
,liste_err
)
130 erreur("Problème à la conversion du tableau OMS. jour_maxi = "+str(jour_maxi
)+" unite = "+unite
,liste_err
)
133 ##################### Création de la figure et du graphique ###################
134 debug("cree_figure : prête à créer la figure",liste_err
)
135 #### La figure, params
137 fig
= plt
.figure(num
=None, figsize
=(conf
["largeur"], conf
["hauteur"]), dpi
=100, facecolor
=conf
["couleurs"]["fond"])
138 plt
.rcParams
['axes.facecolor'] = conf
["couleurs"]["fond"]
139 plt
.rcParams
['axes.edgecolor']= conf
["couleurs"]["cadretxt"]
140 plt
.rcParams
['xtick.color'] = conf
["couleurs"]["cadretxt"]
141 plt
.rcParams
['ytick.color'] = conf
["couleurs"]["cadretxt"]
142 plt
.rcParams
['grid.color'] = conf
["couleurs"]["grille"]
143 plt
.rcParams
['legend.edgecolor'] = conf
["couleurs"]["grille"]
146 ###################### Tracé des différentes courbes
147 #Tracé des courbes OMS
148 for (i
,label
,couleur
) in liste_data_labels
:
149 ax
.plot(coljour
,oms
.extraire_colonne(t
,i
,jour_maxi
),label
=label
,color
=couleur
)
151 debug("cree_figure : tracé des courbes OMS ok",liste_err
)
153 ### Tracé pour de bon
155 ax
.plot(l_jours_conv
,l_poids
,label
=conf
["nom"],color
=conf
["couleurs"]["cadretxt"],marker
='o')
156 debug("Tracé de la courbe enfant, avec les jours "+str(l_jours_conv
),liste_err
)
158 #### extrapolatios éventuelles
159 #print("prolongercourbes" in conf)
160 if conf
["prolongercourbes"] == "oui":
162 # les dates, on prend tous les jours tant qu'à faire
163 date_fin
= int(l_jours
[-1])
164 dates_extrapole
= list(range(date_fin
, jour_maxi
))
165 donnees_extrapole
= prolongecourbe(t
, date_fin
, l_poids
[-1], dates_extrapole
, conf
["typecourbe"], liste_err
)
166 #print("données extrapolées !")
167 dates_extrapole
= u
.convertit_tableau(dates_extrapole
,unite
,liste_err
)
169 # tracé des données extrapolées
170 plt
.plot(dates_extrapole
, donnees_extrapole
,color
=conf
["couleurs"]["cadretxt"], linestyle
=(0, (5,7)), marker
=None)
171 debug("Tracé de la courbe extrapolée ok", liste_err
)
174 debug("On ne trace pas de courbe enfant", liste_err
)
176 ###################" Gestion de l'échelle #####################
177 debug("Courbes tracées. Il n'y a plus qu'à gérer l'échelle", liste_err
)
180 # On extrait la valeur min et la valeur max des poids des courbes OMS et des données
181 (colonne_min
,_
,_
) = liste_data_labels
[-1]
182 (colonne_max
,_
,_
) = liste_data_labels
[0]
185 poids_min
= min(oms
.extraire_colonne(t
,colonne_min
,jour_maxi
))
186 poids_max
= max(oms
.extraire_colonne(t
,colonne_max
,jour_maxi
))
188 poids_min
= min(min(l_poids
),poids_min
)
189 # Pour le poids max, voir la dernière valeur du tableau
191 while i
<len(l_jours
) and l_jours
[i
]<jour_maxi
:
193 poids_max
= max(max(l_poids
[0:i
+1]),poids_max
)
194 # On ajuste un peu ces min et max
195 # min : valeur min -1kg
196 poids_min
= max(0,poids_min
-1)
198 poids_max
= poids_max
* 1.05
202 if conf
["non_sauve"]["grilleamelio"] == "oui":
203 debug("On a choisi la grille plus jolie", liste_err
)
204 pas
=u
.choix_echelle_data(typedonnee
, poids_max
)
206 minechelle
= int(poids_min
/pas
[0])*pas
[0]
208 debug("pas choisis pour l'échelle en y : "+str(pas
), liste_err
)
209 echellemajeure
= arange(minechelle
, poids_max
, pas
[0])
212 echellemineure
= arange(minechelle
, poids_max
, pas
[1])
216 ax
.set_yticks(echellemajeure
, minor
=False)
217 ax
.set_yticks(echellemineure
, minor
=True)
220 pas
=u
.choix_echelle_temps(unite
, age_maxi
)
221 debug("pas choisis pour l'échelle en x : "+str(pas
), liste_err
)
223 echellemajeure
= arange(0,age_maxi
, pas
[0])
225 echellemineure
= arange(0,age_maxi
, pas
[1])
228 ax
.set_xticks(echellemajeure
, minor
=False)
229 ax
.set_xticks(echellemineure
, minor
=True)
231 ################################# Aspect du graphique
233 debug("On commende la déco du graphique", liste_err
)
236 ax
.grid(conf
["grille"]=="oui")
237 ax
.grid(conf
["grille"] == "oui", which
="minor", linestyle
="--")
240 plt
.xlabel("Âge en "+unite
,color
=conf
["couleurs"]["cadretxt"])
241 plt
.ylabel(typedonnee
.capitalize()+" en "+CONFIG
["unites_typedonnees"][typedonnee
],color
=conf
["couleurs"]["cadretxt"])
243 plt
.title(titre
,color
=conf
["couleurs"]["cadretxt"])
245 if l_jours_conv
== []:
246 plt
.axis([0,age_maxi
, poids_min
, poids_max
])
248 plt
.axis([min(0,l_jours_conv
[0]),age_maxi
,poids_min
,poids_max
])
252 if conf
['legende']=="oui":
253 legende
= plt
.legend(loc
=conf
['positionlegende'])
254 plt
.setp(legende
.get_texts(), color
=conf
["couleurs"]["cadretxt"])
259 debug("Fin de cree_figure, tout va bien.", liste_err
)
265 ######################################## Pour extrapoler la courbe
267 def prolongecourbe(tableauOMS
, date
, donnee
, nouvdates
, typecourbe
, liste_err
):
268 """ tableauOMS est le ableau des données OMS. date et donnee sont la date (jours)
269 et la dernière donnée d'où on extrapole. On veut les extrapolations à nouvdate
271 typecourbe est P ou Z. Pour P il faut commencer à regarder à l'indice 4, pour Z
273 On renvoie [] si pas pu extrapoler. """
276 ligneoms
= tableauOMS
[date
]
277 debug("prolongecourbe : Ligne OMS :"+str(ligneoms
)+" valeur de donnée : "+str(donnee
), liste_err
)
280 # On cherche dans quel intervalle on se situe
281 if typecourbe
== "P":
286 while i
<len(ligneoms
) and ligneoms
[i
]<donnee
:
288 debug("prolongecourbe : on a trouvé la valeur de i : "+str(i
),liste_err
)
290 warning("prolongation de courbe : pas réussi... donnée trop haute !", liste_err
)
293 warning("prolongation de courbe : pas réussi... donnée trop basse !", liste_err
)
296 # Le coeff : donnee = coeff * l[i-1]+ (1-coeff)*ligne[i]
297 # On utilisera la même chose pour la nouvelle donnee
298 coeff
= (donnee
- ligneoms
[i
])/(ligneoms
[i
-1] - ligneoms
[i
])
303 ligne2
= tableauOMS
[j
]
304 nouvdonnees
.append(coeff
*ligne2
[i
-1]+ (1-coeff
)*ligne2
[i
])