Courbes et nuages de points (scatter plot) avec python
Voici un code à copier-coller pour avoir un petit jeu de données pour tester les graphiques
hematies = [4.51, 4.92, 4.66, 4.63, 4.67, 4.72, 4.76, 4.76, 4.57, 4.58, 4.46, 4.63, 4.59, 4.46] # nb de globules rouges
vgm = [94.0, 93.0, 93.0, 93.4, 93.4, 94.4, 93.6, 94.3, 94.9, 94.9, 96.8, 95.2, 95.0, 97.2] # taille des globules rouges
Importer le module nécessaire pyplot de matplotlib
import matplotlib.pyplot as plt
1- Graphique de base : plot
Un exemple de graphique de base
import matplotlib.pyplot as plt
plt.plot(hematies,vgm,"ob") # ob = type de points "o" ronds, "b" bleus
plt.show() # Obligatoire pour voir le graphique
Un raccourci utile : quand une fenêtre graphique fait planter la console python qui n'affiche plus ses >>>, faire un ctrl+C
Mise en forme des axes : ajouter un titre à l'axe des abscisses et des ordonnées
plt.plot(hematies,vgm,"ob") # ob = type de points "o" ronds, "b" bleus
plt.ylabel('VGM (taille des globules rouges)')
plt.xlabel('Hématies (nombre de globules rouges)')
plt.show()
Mise en forme des axes : changer les limites des axes x et y
plt.plot(hematies,vgm,"or") # ob = type de points "o" ronds, "r" red
plt.axis([4, 5.5, 90, 100])
plt.show()
Autres fonctions pou séparer les limites de x et y :
plt.ylim(90,100)
plt.xlim(4,5.5)
Afficher les axes sélectivement 4 axes possibles
fig, ax = plt.subplots(figsize=(10, 5))
plt.plot(hematies,vgm,"og") # ob = type de points "o" ronds, "r" red
ax.spines['top'].set_visible(False) ; ax.spines['right'].set_visible(False)
plt.show()
fig, ax = plt.subplots(figsize=(10, 5)) Cette écriture permet d'ajouter des sous propriétés au graphique pour supprimer ses axes.
spines().set_visible() permet d'afficher ou non les axes.
Ajouter un titre
plt.plot(hematies,vgm,marker="s",mec="#57E537",ls="",mfc="red")
plt.title("Titre du graphique")
plt.show()
Voici ainsi un graphique pourvu d'un titre. ls (type de ligne) a permis d'inactiver les lignes. On a pu jouer subtilement sur la forme de marker (marker) et les couleurs internes (mfc) et périphériques (mec) des points.
Changer les types de points ou de traits
plt.plot([1, 2, 3, 4],[4 ,5,10,7],"-gs") # green carré
plt.plot([2,3],[6,11],"-k") # ligne noire
plt.plot([2,3],[8,13],"^b") # triangle blue
plt.plot([2,3],[9,14],"--c") # ligne cyan pointillé
plt.plot([2,3],[10,15],"-vy") # ligne yellow triangle à l'envers
plt.ylabel('ylab')
plt.xlabel('xlab')
plt.axis([0, 6, 0, 20])
plt.show()
# Aller plus loin
help(plt.plot)
On voit dans cet exemple que la superposition de graphiques est très simple ! Il suffit d'insérer plusieurs lignes entre le premier tracé et la ligne plt.show().
Plusieurs courbes superposées, des points ronds, triangulaires, des changements de couleur, des traits ou des pointillés
2- Réaliser un scatter-plot : sensus stricto, un nuage de points dont les points changent de taille ou de couleur
Colorer les points en fonction de leurs catégories
Un exemple simple à reprendre :
cate = ["f","m","f","f","m"]
import pandas as pd
cate = pd.Series(cate)
plt.scatter([1,2,3,4,5],[1,2,3,4,5],c=cate.apply(lambda x : cat[x])) ; plt.show()
Prenons un jeu de données poids, tailles et IMC de filles et garçons (code à copier-coller directement pour simuler ces valeurs)
import numpy as np
from numpy.random import normal as norm # On tapera ainsi norm() au lien de np.random.normal()
import pandas as pd
f_poids = list(norm(loc = 55, size=20, scale=11)) # Conversion en list nécessaire pour faire des concaténation avec +
f_taille = list(norm(loc = 163, size=20, scale=14))
m_poids = list(norm(loc = 70, size=20, scale=11))
m_taille = list(norm(loc = 175, size=20, scale=15))
poids = f_poids+m_poids ; poids = np.array(poids) # conversion np.array nécessaire pour multiplier et additionner des listes
taille = f_taille+m_taille ; taille = np.array(taille)
imc = poids/(taille/100)**2
sexe = ["F"]*20+["M"]*20
compil = {"Sexe" : sexe , "Poids" : poids, "Taille" : taille, "IMC" : imc}
compil = pd.DataFrame(compil) ; print(compil)
1) Méthode la plus simple : colorer avec seaborn
import seaborn as sns
On peut colorer les points selon une variable de catégories : ici, le sexe
sns.relplot(x="Poids",y="Taille",hue="Sexe",data=compil,height=6,s=70) ; plt.show()
On peut aussi colorer les points en fonction d'une 3ème variable numérique
sns.relplot(x="Poids",y="Taille",hue="IMC",data=compil,height=6,s=70) ; plt.show()
2) Méthode relativement simple pour coloriser par catégories : en utilisant le format dataframe/category de pandas
# Chargement de données
import seaborn as sns ; iris = sns.load_dataset('iris')
# Détermination de la colonne de catégories
Species = iris.iloc[:,4] ; colors = Species.astype('category') ; print(colors.cat.codes)
# Tracer le scatter plot
import matplotlib.pyplot as plt
plt.scatter(iris.iloc[:,1],iris.iloc[:,2],c=colors.cat.codes)
plt.show()
3) Colorier subtilement les points en fonction des catégories (méthode de base avec seulement 2 catégories)
1) Prenons le jeu de données de l'exemple compil ci-dessus
value=(compil['Poids']>80) & (compil['Sexe']=="M") # Pour coloriser les hommes de plus de 80 kg
compil['color']= np.where( value==True , "red", "#3498db")
plt.scatter(compil.Poids,compil.IMC,color= compil.color) ; plt.show()
4) Méthode plus subtile, paramétrage fin des caractéristiques de chaque catégorie :
4.1) Définir les caractéristiques des points de chaque catégorie (Homme (M) et Femmes (F))
colors = {'F':'pink', 'M':'blue'} # Définition des colorations par catégories
cex = {'F':40, 'M':10} # Définition des tailles de points par catégories
pch = {'F':"o", 'M':"s"} # Définition des types de marqueurs par catégories
4.2) Tracer le graphique en utilisant la fonction apply(lambda x : dic[x]) pour changer les points selon les catégories
import matplotlib.pyplot as plt
plt.scatter(compil.Poids,compil.Taille,
c=compil.Sexe.apply(lambda x: colors[x]),
s=compil.Sexe.apply(lambda x: cex[x]),
marker="s")
plt.xlabel("Poids (kg)") ; plt.ylabel("IMC")
plt.title("Relation poids IMC de filles et garçons")
plt.show()
Un exemple brut de bubble chart
Simuler des données (code à copier-coller) :
# Données
data = {'x': np.arange(50),
'y': np.arange(50) + 10 * np.random.randn(50),
'taille': np.abs(np.random.randn(50)*100),
'color': np.random.randint(0, 50, 50)}
Tracer le bubble chart
from matplotlib import pyplot as plt
# Scatter plot (plot à point avec palette de couleur par défaut Viridis()
# scatter(x,y,c=color, s=taille)
plt.scatter('x', 'y', c='color', s='taille', data=data)
plt.xlabel('entry a')
plt.ylabel('entry b')
cbar= plt.colorbar()
cbar.set_label("Variable de coloration", labelpad=+1)
plt.show()
Gradient de couleur mise sous forme de barre de couleur légendée.
3- Superposer de l'information (droites de régressions linéaires, verticales, texte, flèches)
Ajouter un commentaire, du texte sur le graphique
plt.scatter(hematies,vgm,marker="s",color="#57E537")
plt.text(4.6,96,"Ici un commentaire",fontsize=12)
plt.show()
commande à retenir : plt.text()
Tracer des lignes verticales et horizontales sur le graphique
plt.scatter(hematies,vgm,marker="s",color="#FB0BD6")
import numpy as np # pour calculer les moyennes de x et y dans cet exemple
# Traits vertical et horizontal (R abline in python)
plt.axvline(x=np.mean(hematies),color="k")
plt.axhline(y=np.mean(vgm),color="g",linewidth=10) # linewidth permet de jouer sur l'épaisseur
plt.show()
commandes à retenir : plt.axvline() et plt.axhline()
Tracer une droite de régression linéaire
Tracer une flèche (méthode simple (et moche) et méthode complexe (et belle))
plt.scatter(hematies,vgm,marker="s",color="#22FBD6")
# Méthode 1 - coordonnées de départ, hauteur et largeur
plt.arrow(4.8, 96,-0.1,-1.2, head_width=0.05, head_length=0.50, fc='red', ec='blue')
# Méthode 2 avec la fonction annotate (flèche cyan dans l'exemple)
plt.annotate('dernier point', xy = (4.65, 94.5), xytext = (4.5, 93),
arrowprops = {'facecolor': 'cyan', 'edgecolor': 'cyan',
'width': 15, 'headwidth': 30, 'shrink': 0.1})
plt.show()
commandes à retenir : plt.arrow() et plt.annotate()
Tracer une ellipse de confiance
hematies = np.array(hematies)
vgm = np.array(vgm)
fig, ax = plt.subplots()
plt.scatter(hematies,vgm,marker="s",color="#22FBD6")
confidence_ellipse(hematies, vgm , ax, edgecolor='red') # nécessite la fonction confidence_ellipse (cf. lien)
plt.show()
Tracer une nappe convexe (convexe hull) : entourer un nuage de points
from scipy.spatial import ConvexHull
points = np.random.rand(30, 2) # 30 random points in 2-D
hull = ConvexHull(points)
import matplotlib.pyplot as plt
plt.plot(points[:,0], points[:,1], 'o')
for simplex in hull.simplices:
plt.plot(points[simplex, 0], points[simplex, 1], 'k-')
#plt.plot(points[hull.vertices,0], points[hull.vertices,1], 'r--', lw=2)
#plt.plot(points[hull.vertices[0],0], points[hull.vertices[0],1], 'ro')
plt.show()
4- Ajouter une légende
Ajouter une légende (méthode simple, à paramétrer manuellement)
1) Prenons un jeu de données poids et tailles de filles et garçons
poids = [60,50,40,35,55,48,65,67,58,55,72]
taille = [173,135,140,150,150,160,165,170,180,177,178]
sexe = ["F"]*5+["M"]*6
color = ["pink"]*5+["blue"]*6
2) Traçons le graphique
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
plt.scatter(poids,taille,
c=color)
pop_f = mpatches.Patch(color='pink', label='F')
pop_m = mpatches.Patch(color='blue', label='M')
plt.legend(handles=[pop_f,pop_m])
plt.show()
Dans cet exemple, la légende ne se construit pas automatiquement, elle est paramétrée manuellement.
3) Même exemple, légende sur courbes
plt.plot(list(range(0,5)),[1,2,3,4,7],label="boys",c="blue")
plt.plot(list(range(0,5)),[0.5,1.5,2.5,5,6],label="girls",c="pink")
plt.legend()
plt.show()
Ajouter une légende (méthode simple, à paramétrer semi-automatiquement)
1) Voici un jeu de données à colorer par catégories ("F", "M", et "NA" non caractérisée)
poids = [60,50,40,35,55,48,65,67,58,55,72]
taille = [173,135,140,150,150,160,165,170,180,177,178]
sexe = ["F"]*5+["NA"]+["M"]*5
compil = {"Poids":poids, "Taille":taille, "Sexe":sexe} # Etape de mise en dictionnaire avant conversion en dataframe
import pandas as pd
compil = pd.DataFrame(compil) # Les données doivent être au format dataframe
2) Définir les caractéristiques de chaque catégorie au format dictionnaire
category = {'F':0, 'M':1, 'NA':2} # Numéroter les catégories
col = {'F':'pink', 'M':'blue', 'NA':'green'} # Définition des colorations par catégories
cex = {'F':60, 'M':40, 'NA':70} # Définition des tailles de points par catégories
pch = {'F':"o", 'M':"s", 'NA':'^'} # Définition des types de marqueurs par catégories
3) Réaliser une liste des couleurs et des formes de chaque point pour chaque catégorie
col_s = compil.Sexe.apply(lambda x: col[x])
cex_s = compil.Sexe.apply(lambda x: cex[x])
pch_s = compil.Sexe.apply(lambda x: pch[x])
category_s = compil.Sexe.apply(lambda x: category[x])
4) Tracer. La seule façon d'avoir une légende qui prenne automatiquement en compte les caractéristiques de chaque catégorie est de les tracer les unes après les autres (boucle for ou n lignes à copier-coller)
fig, ax = plt.subplots(figsize=(10, 5))
for i in range(3) :
print("Voici la catégorie : ",i)
ax.scatter(compil.Poids[category_s==i],compil.Taille[category_s==i],
c=col_s[category_s==i], s=cex_s[category_s==i],
marker="o",label=list(cex.keys())[i])
ax.legend() ; ax.grid(True)
plt.show()
5- Ajouter des barres d'erreur
Ajouter des barres d'erreur avec la fonction errorbar()
x = list(range(1,11,1)) ; y = [2,4,3,5,4,6,7,8,9,8]
erreur = [1,0.5,2,1,0.5,0.5,1,2,1,2] # Classiquement, l'erreur est un intervalle de confiance
import matplotlib.pyplot as plt
plt.scatter(x,y,s=50) ; # Tracer le nuage de points
# Ajouter les barres d'erreur
plt.errorbar(x,y, yerr= erreur, # yerr : barres verticales, xerr : barres horizontales
ecolor = "#0B1131",capsize = 7, # capsize : longueur du trait horizontal
elinewidth = 3,capthick = 3, # epaisseurs de la barre d'erreur et du trait horizontal
fmt="none") ; plt.grid() ; plt.show()
On constate un petit problème : les points sont derrières les barres d'erreur (et c'est moche)
Tracer scatter-plot et barres d'erreur avec la fonction errorbar() pour ne plus avoir les points derrière
plt.errorbar(x,y, yerr= erreur,
ecolor = "#0B1131",capsize = 7, # Couleur au format html : pour éditer
elinewidth = 3,capthick = 3,
fmt="-ro") ; plt.show() # -ro : comme pour plot : lignes ("-") rouge ("r") avec des points ronds ("o")
Là, c'est mieux...
Et si je voulais des barres horizontales en plus :
x = list(range(1,11,1)) ; y = [2,4,3,5,4,6,7,8,9,8]
y_erreur = [1,0.5,0.5,1,0.5,0.5,1,0.5,1,0.6]
x_erreur = [1,0.5,1,1,0.5,0.5,1,0.5,1,1]
plt.errorbar(x,y, yerr= y_erreur,xerr = x_erreur,
ecolor = "green",capsize = 4,
elinewidth = 2,capthick = 2,
fmt="-bo") ; plt.show()
6- Scatter plot 3D - courbe 3D - graphique y = f(x1*x2) en 3D
6.1- Scatter 3D simple
# Voici des données simulées
import numpy as np
x = np.random.normal(size=15,loc=10,scale=3)
y = np.random.normal(size=15,loc=10,scale=3)
z = np.random.normal(size=15,loc=10,scale=3)
# Tracer le graphique
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.scatter(x,y,z, zdir='z',s=40,depthshade=True)
# Paramétrer le graphique
ax.set_xlim3d([0.0, 20.0]) ; ax.set_xlabel('X')
ax.set_ylim3d([0.0, 20.0]) ; ax.set_ylabel('Y')
ax.set_zlim3d([0.0, 20.0]) ; ax.set_zlabel('Z')
# Afficher
plt.show()
6.2- Scatter 3D et nuages de points mutiples
Voici des nuages de points tracés ligne par ligne
# Voici un jeu de données pour 3 nuages de points
import numpy as np
data1 = (np.random.normal(size=15,loc=10,scale=3),
np.random.normal(size=15,loc=15,scale=3),
np.random.normal(size=15,loc=10,scale=4))
data2 = (np.random.normal(size=15,loc=15,scale=4),
np.random.normal(size=15,loc=15,scale=3),
np.random.normal(size=15,loc=15,scale=3))
data3 = (np.random.normal(size=15,loc=14,scale=3),
np.random.normal(size=15,loc=13,scale=5),
np.random.normal(size=15,loc=10,scale=3))
# Affichage simple ligne par ligne
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.scatter(data1[0],data1[1],data1[2],c="red",s=40)
ax.scatter(data2[0],data2[1],data2[2],c="green",s=40)
ax.scatter(data3[0],data3[1],data3[2],c="blue",s=40)
plt.show()
Axes3D.scatter() pour tracer les nuages
Voici des nuages de points tracés avec une mise en forme automatique (on reprend les données de l'exemple ci-dessus)
datas = (data1, data2, data3)
colors = ("red", "green", "blue")
groups = ("env1", "env2", "env3")
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# Configurer le graphique
fig = plt.figure()
ax = fig.gca(projection='3d')
# Ajouter les 3 nuages de points
for d, c, g in zip(datas, colors, groups):
x, y, z = d # on découpe chaque paquet en x, y, z
ax.scatter(x, y, z, alpha=0.8, c=c, s=30, label=g)
# Affichage
plt.title('Nuages de points 3D')
plt.legend(loc=2)
# Affichage
plt.show()
plt.legend() pour ajouter une légende.
Une boucle for pour tracer les nuages
6.3- Afficher une nappe 3D
Nappe 3D : surfaçage d'un nuage de points
# Des données à surfacer
import numpy as np
x = np.random.normal(size=15,loc=10,scale=3)#;x.sort()
y = np.random.normal(size=15,loc=10,scale=3)#;y.sort()
z = x**2 + y**2 - 3*x - 3*y - 3
# Afficher le graphique
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_trisurf(x, y, z, cmap = "viridis")
plt.show()
Axes3D.plot_trisurf()
Lissage 3D : surface d'une courbe 3D
# Données simulées
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
# Grille de lissage faite pour toutes valeur de X et Y (équivalent de expand.grid() de R)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# Affichage de la nappe
fig = plt.figure()
ax = fig.gca(projection='3d')
surface = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap="plasma",
linewidth=0, antialiased=False)
ax.set_zlim(-1.01, 1.01)
fig.colorbar(surface, shrink=0.5, aspect=5)
plt.show()
Grille faite avec numpy.meshgrid() et surface faire avec Axes3D.plot_surface()
6.4- Sauvegarder un graphique 3D au format GIF animé
Pour sauvegarder un gif animé, copier-coller ce code en l'insérant juste avec la dernière ligne plt.show()
print("Faire une animation")
def rotate(angle):
ax.view_init(azim=angle)
import matplotlib.animation as animation; animation.writers.list()
rot_animation = animation.FuncAnimation(fig, rotate, frames=np.arange(0, 362, 2), interval=100)
import os as os
os.chdir("C:/dossier") # A personnaliser en mettant des / à la place des \
rot_animation.save('rotation.gif', dpi=80, writer='pillow')
7- Kernel density - Nappes convexes : jeu de données denses
7.1- Kernel density
Un exemple de données : les données iris.
import seaborn as sns
print(sns.get_dataset_names())
iris = sns.load_dataset("iris") ; print(iris.head())
x_c = iris.iloc[:,0]
y_c = iris.iloc[:,1]
Affichage d'un graphique de densité simple
sns.set_style("white")
sns.kdeplot(x="sepal_length",y="sepal_width",data=iris) # Traits de contours
sns.kdeplot(x="sepal_length",y="sepal_width",data=iris, cmap="hot", shade=True, thresh=0)
plt.show()
En changeant un peu la mise en forme...
sns.set_style("white")
sns.kdeplot(x="sepal_length",y="sepal_width",data=iris, cmap="Blues", shade=True)
plt.show()
En croisant plusieurs catégories...
sns.kdeplot(x="sepal_length",y="sepal_width",data=iris[iris.species=="setosa"], cmap="YlGn",shade=True, thresh=0.25,alpha=0.5)
sns.kdeplot(x="sepal_length",y="sepal_width",data=iris[iris.species=="versicolor"], cmap="YlOrBr",shade=True, thresh=0.25,alpha=0.5)
sns.kdeplot(x="sepal_length",y="sepal_width",data=iris[iris.species=="virginica"], cmap="Purples",shade=True, thresh=0.25,alpha=0.5)
plt.show()
7.2- Nappes convexes
On peut entourer les nuages de points de chaque catégories ou d'un nuage de points simple lorsqu'on a trop de points à afficher. Une ellipse à 95% est tout aussi envisageable... cf. ci-dessus dans cette page...
Nappes convexes entourant 3 nuages de points
Nappes convexes seules pour alléger l'affichage
En reprenant x_c et y_c de l'exemple ci-dessus des données iris.
Définir une variable de catégories :
cat = df.Series(iris.species).astype("category")
Importer les modules nécessaires et définir une couleur automatique pour chaque catégorie :
import numpy as np
from scipy.spatial import ConvexHull
# Définir les couleurs des nappes convexes
import matplotlib.cm as cm
import matplotlib as mpl
norm = mpl.colors.Normalize(vmin=0, vmax=(len(np.unique(cat.cat.codes)))) #-(len(np.unique(c)))
cmap = "viridis_r" # "YlGn"
m = cm.ScalarMappable(norm=norm, cmap=cmap)
Affichage
# Optionnel et à éviter si on a trop de points : affichage des points
plt.scatter(x_c,y_c, c = cat.cat.codes,cmap="viridis_r")
# Affichage des nappes convexes qui entourent chaque catégorie
for cat_temp in cat.cat.codes.unique() :
x_c_temp = [x_c[i] for i in range(len(x_c)) if (cat.cat.codes[i] == cat_temp)]
y_c_temp = [y_c[i] for i in range(len(y_c)) if (cat.cat.codes[i] == cat_temp)]
# Former pour chaque couple (X;Y) d'une catégorie, une nappe de points
points = [ [ None ] * len(x_c_temp) ] * 2
points = np.array(points)
points = points.reshape(len(x_c_temp),2)
points[:,0] = x_c_temp
points[:,1] = y_c_temp
# Déterminer les coordonnées de la nappe qui entoure ces points
hull = ConvexHull(points)
temp = 0
# Coloration puis tracé de la nappe convexe
for simplex in hull.simplices:
color_temp = m.to_rgba(cat_temp)
plt.plot(points[simplex, 0], points[simplex, 1],color=color_temp)#, linestyle='dashed')#linewidth=2,color=cat)
plt.show()
Même chose avec une ellipse de confiance : Pensez à télécharger la fonction confidence_ellipse()
#####
# ELLIPSE DE CONFIANCE
####
fig, ax = plt.subplots()
plt.scatter(diamonds.carat,diamonds.price,color="white")
for cat_temp in cat.cat.codes.unique() :
print("Patience...")
x_c_temp = [x_c[i] for i in range(len(x_c)) if (cat.cat.codes[i] == cat_temp)]
y_c_temp = [y_c[i] for i in range(len(y_c)) if (cat.cat.codes[i] == cat_temp)]
# Former pour chaque couple (X;Y) d'une catégorie, une nappe de points
points = [ [ None ] * len(x_c_temp) ] * 2
points = np.array(points)
points = points.reshape(len(x_c_temp),2)
points[:,0] = x_c_temp
points[:,1] = y_c_temp
x_c_temp = np.array(x_c_temp)
y_c_temp = np.array(y_c_temp)
# Déterminer les coordonnées de la nappe qui entoure ces points
color_temp = m.to_rgba(cat_temp)
confidence_ellipse(x_c_temp , y_c_temp , ax, edgecolor=color_temp)
temp = 0
# Coloration puis tracé de la nappe convexe
# for simplex in hull.simplices:
# color_temp = m.to_rgba(cat_temp)
# plt.plot(points[simplex, 0], points[simplex, 1],color=color_temp)#, linestyle='dashed')#linewidth=2,color=cat)
plt.show()
8- Sauvegarder un graphique au format image
1- Définir d'abord le répertoire source (répertoire de sauvegarde) - cf. aide à la gestion des sources/documents
import os as os
os.chdir("C:/Users/python") # remplacer \ par /
2- Tracer le graphique et sauvegarder dans la foulée
plt.scatter(hematies,vgm,marker="s",color="black")
plt.savefig("test.png", bbox_inches='tight')
Sources externes
A étudier pour la légende : https://stackoverflow.com/questions/26139423/plot-different-color-for-different-categorical-levels-using-matplotlib
Types de scatter : https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.scatter.html
Mise en forme des police avec kwargs : https://matplotlib.org/3.1.0/gallery/text_labels_and_annotations/fonts_demo_kw.html