matplotlib
La bibliothèque
Matplotlib est une bibliothèque de tracé deux dimensions pour python.
D’une très grande richesse, elle propose en autres :
– tous les types classiques de tracé : courbes, histogrammes, diagrammes à barres, nuages de points, etc.
– un mode à la Matlab® avec pylab (utilisé dans l’exemple ci-dessous)
– une intégration facile avec des applications web et six bibliothèques d’interface graphique (Qt, gtk, etc.)
– export des figures en de nombreux formats, dont le SVG.
La documentation
La documentation de Matplotlib est excellente, surtout grâce à la galerie d’exemples illustrés : Matplotlib — Thumbnail gallery
Autres sources d’exemples et d’astuces :
– Cookbook/Matplotlib -
– Plotting data using Matplotlib : Part 2
Un exemple
Comme exemple, je vous propose de tracer les courbes de croissance standards de l’OMS disponible au lien suivant : WHO
Sans être une référence, il y a surement mille façons de faire cela, ce script concentre de nombreuses astuces glanées au fil du temps, comme :
– sélection des couleurs dans un color map
– lecture directe des fichiers CSV
– axes partagés
– min max des axes imposés
– masquage des repères d’axe
– etc.
# -*- coding:utf-8 -*-
"""
Drawing Standard Child Grow curve with Matplotlib
More info : http://intrw.net/log/spip.php?article149
"""
import pylab
def getColor(name, n):
# Usage name is one of the cm (colormaps) names
# cl = getColor('jet', 4)
# then call cl(i) with i between 1 and n
# A list of cm is available here:
# http://matplotlib.sourceforge.net/
# examples/pylab_examples/show_colormaps.html
import matplotlib.cm as cm
return cm.get_cmap(name, lut=n+2)
# Define text box appearance
percent_box = dict(boxstyle="round",
ec='none',
fc='w',
alpha=0.5)
#
# Load data
#
# Load boys data
boys_bfa = pylab.csv2rec('bfa_boys_p_exp.txt', delimiter='\t')
boys_lhfa = pylab.csv2rec('lhfa_boys_p_exp.txt', delimiter='\t')
boys_wfa = pylab.csv2rec('wfa_boys_p_exp.txt', delimiter='\t')
# Load girls data
girls_bfa = pylab.csv2rec('bfa_girls_p_exp.txt', delimiter='\t')
girls_lhfa = pylab.csv2rec('lhfa_girls_p_exp.txt', delimiter='\t')
girls_wfa = pylab.csv2rec('wfa_girls_p_exp.txt', delimiter='\t')
f = pylab.figure()
#
# Boys
#
# Get boys color list
cl = getColor('PuBu', 3)
# Plot body mass index boy data
ax1 = pylab.subplot(321)
ax1.grid(True)
pylab.fill_between(boys_bfa.day, boys_bfa.p3, 0, color= cl(1), alpha=0.5)
pylab.plot(boys_bfa.day, boys_bfa.p3, color= cl(1))
pylab.plot(boys_bfa.day, boys_bfa.p15, color= cl(2))
pylab.plot(boys_bfa.day, boys_bfa.p50, color= cl(3))
pylab.plot(boys_bfa.day, boys_bfa.p85, color= cl(2))
pylab.plot(boys_bfa.day, boys_bfa.p97, color= cl(1))
pylab.fill_between(boys_bfa.day, boys_bfa.p97,
max(max(boys_bfa.p97), max(boys_bfa.p97))*1.2,
color= cl(1), alpha=0.5)
# Add percentage for BMI boy data
pylab.text(max(boys_bfa.day)-10, boys_bfa.p3[-1:], "3%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_bfa.day)-10, boys_bfa.p15[-1:], "15%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_bfa.day)-10, boys_bfa.p50[-1:], "50%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_bfa.day)-10, boys_bfa.p85[-1:], "85%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_bfa.day)-10, boys_bfa.p97[-1:], "97%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.xlim(0, max(boys_bfa.day))
pylab.ylim(min(min(girls_bfa.p3), min(boys_bfa.p3))*0.8,
max(max(boys_bfa.p97), max(boys_bfa.p97))*1.2)
pylab.title(u"Boys")
#~ pylab.xlabel(u"Days")
pylab.ylabel(u"BMI (kg/m²)")
# Plot lenght heigh boy data
ax3 = pylab.subplot(323)
ax3.grid(True)
pylab.fill_between(boys_lhfa.day, boys_lhfa.p3, 0, color= cl(1), alpha=0.5)
pylab.plot(boys_lhfa.day, boys_lhfa.p3, color= cl(1))
pylab.plot(boys_lhfa.day, boys_lhfa.p15, color= cl(2))
pylab.plot(boys_lhfa.day, boys_lhfa.p50, color= cl(3))
pylab.plot(boys_lhfa.day, boys_lhfa.p85, color= cl(2))
pylab.plot(boys_lhfa.day, boys_lhfa.p97, color= cl(1))
pylab.fill_between(boys_lhfa.day, boys_lhfa.p97,
max(max(girls_lhfa.p97), max(boys_lhfa.p97))*1.2,
color= cl(1), alpha=0.5)
# Add percentage for lenght / height boy data
pylab.text(max(boys_lhfa.day)-10, boys_lhfa.p3[-1:], "3%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_lhfa.day)-10, boys_lhfa.p15[-1:], "15%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_lhfa.day)-10, boys_lhfa.p50[-1:], "50%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_lhfa.day)-10, boys_lhfa.p85[-1:], "85%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_lhfa.day)-10, boys_lhfa.p97[-1:], "97%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.xlim(0, max(boys_lhfa.day))
pylab.ylim(min(min(girls_lhfa.p3), min(boys_lhfa.p3))*0.8,
max(max(girls_lhfa.p97), max(boys_lhfa.p97))*1.2)
#~ pylab.xlabel(u"Days")
pylab.ylabel(u"Height (cm)")
# Plot weight boy data
ax5 = pylab.subplot(325)
ax5.grid(True)
pylab.fill_between(boys_wfa.day, boys_wfa.p3, 0, color= cl(1), alpha=0.5)
pylab.plot(boys_wfa.day, boys_wfa.p3, color= cl(1))
pylab.plot(boys_wfa.day, boys_wfa.p15, color= cl(2))
pylab.plot(boys_wfa.day, boys_wfa.p50, color= cl(3))
pylab.plot(boys_wfa.day, boys_wfa.p85, color= cl(2))
pylab.plot(boys_wfa.day, boys_wfa.p97, color= cl(1))
pylab.fill_between(boys_wfa.day, boys_wfa.p97,
max(max(girls_wfa.p97), max(girls_wfa.p97))*1.2,
color= cl(1), alpha=0.5)
# Add percentage for weight boy data
pylab.text(max(boys_wfa.day)-10, boys_wfa.p3[-1:], "3%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_wfa.day)-10, boys_wfa.p15[-1:], "15%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_wfa.day)-10, boys_wfa.p50[-1:], "50%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_wfa.day)-10, boys_wfa.p85[-1:], "85%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(boys_wfa.day)-10, boys_wfa.p97[-1:], "97%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.xlim(0, max(boys_wfa.day))
pylab.ylim(min(min(girls_wfa.p3), min(boys_wfa.p3))*0.8,
max(max(girls_wfa.p97), max(girls_wfa.p97))*1.2)
pylab.xlabel(u"Days")
pylab.ylabel(u"Weight (kg)")
#
# Girls
#
# Get a girly color list
cl = getColor('PuRd', 3)
# Plot body mass index girl data
ax2 = pylab.subplot(322)
ax2.grid(True)
pylab.fill_between(girls_bfa.day, girls_bfa.p3, 0, color= cl(1), alpha=0.5)
pylab.plot(girls_bfa.day, girls_bfa.p3, color= cl(1))
pylab.plot(girls_bfa.day, girls_bfa.p15, color= cl(2))
pylab.plot(girls_bfa.day, girls_bfa.p50, color= cl(3))
pylab.plot(girls_bfa.day, girls_bfa.p85, color= cl(2))
pylab.plot(girls_bfa.day, girls_bfa.p97, color= cl(1))
pylab.fill_between(girls_bfa.day, girls_bfa.p97,
max(max(girls_bfa.p97), max(boys_bfa.p97))*1.2,
color= cl(1), alpha=0.5)
# Add percentage for BMI girl data
pylab.text(max(girls_bfa.day)-10, girls_bfa.p3[-1:], "3%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_bfa.day)-10, girls_bfa.p15[-1:], "15%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_bfa.day)-10, girls_bfa.p50[-1:], "50%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_bfa.day)-10, girls_bfa.p85[-1:], "85%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_bfa.day)-10, girls_bfa.p97[-1:], "97%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.xlim(0, max(girls_bfa.day))
pylab.ylim(min(min(girls_bfa.p3), min(boys_bfa.p3))*0.8,
max(max(girls_bfa.p97), max(boys_bfa.p97))*1.2)
pylab.title(u"Girls")
# No label
#~ pylab.xlabel(u"Days")
#~ pylab.ylabel(u"Body mass index (kg/m²)")
# Plot lenght heigh girl data
ax4 = pylab.subplot(324)
ax4.grid(True)
pylab.fill_between(girls_lhfa.day, girls_lhfa.p3, 0, color= cl(1), alpha=0.5)
pylab.plot(girls_lhfa.day, girls_lhfa.p3, color= cl(1))
pylab.plot(girls_lhfa.day, girls_lhfa.p15, color= cl(2))
pylab.plot(girls_lhfa.day, girls_lhfa.p50, color= cl(3))
pylab.plot(girls_lhfa.day, girls_lhfa.p85, color= cl(2))
pylab.plot(girls_lhfa.day, girls_lhfa.p97, color= cl(1))
pylab.fill_between(girls_lhfa.day, girls_lhfa.p97,
max(max(girls_lhfa.p97), max(boys_lhfa.p97))*1.2,
color= cl(1), alpha=0.5)
# Add percentage for lenght / height girl data
pylab.text(max(girls_lhfa.day)-10, girls_lhfa.p3[-1:], "3%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_lhfa.day)-10, girls_lhfa.p15[-1:], "15%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_lhfa.day)-10, girls_lhfa.p50[-1:], "50%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_lhfa.day)-10, girls_lhfa.p85[-1:], "85%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_lhfa.day)-10, girls_lhfa.p97[-1:], "97%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.xlim(0, max(girls_lhfa.day))
pylab.ylim(min(min(girls_lhfa.p3), min(boys_lhfa.p3))*0.8,
max(max(girls_lhfa.p97), max(boys_lhfa.p97))*1.2)
# No label
#~ pylab.xlabel(u"Days")
#~ pylab.ylabel(u"Length/height (cm)")
# Plot weight girl data
ax6 = pylab.subplot(326)
ax6.grid(True)
pylab.fill_between(girls_wfa.day, girls_wfa.p3, 0, color= cl(1), alpha=0.5)
pylab.plot(girls_wfa.day, girls_wfa.p3, color= cl(1))
pylab.plot(girls_wfa.day, girls_wfa.p15, color= cl(2))
pylab.plot(girls_wfa.day, girls_wfa.p50, color= cl(3))
pylab.plot(girls_wfa.day, girls_wfa.p85, color= cl(2))
pylab.plot(girls_wfa.day, girls_wfa.p97, color= cl(1))
pylab.fill_between(girls_wfa.day, girls_wfa.p97,
max(max(girls_wfa.p97), max(boys_wfa.p97))*1.2,
color= cl(1), alpha=0.5)
# Add percentage for weight girl data
pylab.text(max(girls_wfa.day)-10, girls_wfa.p3[-1:], "3%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_wfa.day)-10, girls_wfa.p15[-1:], "15%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_wfa.day)-10, girls_wfa.p50[-1:], "50%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_wfa.day)-10, girls_wfa.p85[-1:], "85%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.text(max(girls_wfa.day)-10, girls_wfa.p97[-1:], "97%", size=10,
ha="right", va="center",
bbox = percent_box)
pylab.xlim(0, max(girls_wfa.day))
pylab.ylim(min(min(girls_wfa.p3), min(boys_wfa.p3))*0.8,
max(max(girls_wfa.p97), max(boys_wfa.p97))*1.2)
pylab.xlabel(u"Days")
# No label
#~ pylab.ylabel(u"Weight (kg)")
pylab.subplots_adjust(hspace=0.001, wspace=0.001)
#
# Personalise graph
#
# Main title
pylab.figtext(0.5, 0.960, 'Standard Grow Curves',
ha='center', color='black', weight='bold', size='large')
# Hide non wished tick labels
xticklabels = (ax1.get_xticklabels() + ax2.get_xticklabels()
+ ax3.get_xticklabels() + ax4.get_xticklabels())
pylab.setp(xticklabels, visible=False)
yticklabels = (ax2.get_yticklabels()
+ ax4.get_yticklabels()
+ ax6.get_yticklabels())
pylab.setp(yticklabels, visible=False)
#
# Finally display graph
#
pylab.show()
P.-S.
Les liens directs vers les fichiers utilisés dans le script :
– lhfa boys [txt 104kb] : http://www.who.int/entity/childgrowth/standards/lhfa_boys_p_exp.txt
– lhfa girls [txt 104kb] : http://www.who.int/entity/childgrowth/standards/lhfa_girls_p_exp.txt
– wfa boys [txt 97kb] : http://www.who.int/entity/childgrowth/standards/wfa_boys_p_exp.txt
– wfa girls [txt 97kb] : http://www.who.int/entity/childgrowth/standards/wfa_girls_p_exp.txt
– bfa boys [txt 101kb] : http://www.who.int/entity/childgrowth/standards/bfa_boys_p_exp.txt
– bfa girls [txt 101kb] : http://www.who.int/entity/childgrowth/standards/bfa_girls_p_exp.txt