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