Introduction
Ce laboratoire vous guidera dans l'annotation de graphes avec Matplotlib. Vous allez apprendre à souligner des points d'intérêt spécifiques et à utiliser divers outils visuels pour attirer l'attention sur ces points. Les outils d'annotation et de texte sont essentiels pour communiquer des informations et rendre les graphes plus visuellement attrayants.
Conseils sur la machine virtuelle
Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter Notebook pour pratiquer.
Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations du carnet Jupyter Notebook.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez des commentaires après la session, et nous résoudrons rapidement le problème pour vous.
Spécification des points de texte et des points d'annotation
Vous devez spécifier un point d'annotation xy=(x, y) pour annoter ce point. De plus, vous pouvez spécifier un point de texte xytext=(x, y) pour la position du texte de cette annotation. Facultativement, vous pouvez spécifier le système de coordonnées de xy et xytext avec l'une des chaînes suivantes pour xycoords et textcoords (valeur par défaut : 'data') :
- 'points de figure' : points à partir du coin inférieur gauche de la figure
- 'pixels de figure' : pixels à partir du coin inférieur gauche de la figure
- 'fraction de figure' : (0, 0) est le coin inférieur gauche de la figure et (1, 1) est le coin supérieur droit
- 'points d'axes' : points à partir du coin inférieur gauche des axes
- 'pixels d'axes' : pixels à partir du coin inférieur gauche des axes
- 'fraction d'axes' : (0, 0) est le coin inférieur gauche des axes et (1, 1) est le coin supérieur droit
- 'points d'offset' : Spécifiez un décalage (en points) à partir de la valeur xy
- 'pixels d'offset' : Spécifiez un décalage (en pixels) à partir de la valeur xy
- 'data' : utiliser le système de coordonnées de données des axes
Remarque : pour les systèmes de coordonnées physiques (points ou pixels), l'origine est le (bas, gauche) de la figure ou des axes.
Facultativement, vous pouvez spécifier les propriétés de la flèche qui trace une flèche du texte au point annoté en donnant un dictionnaire de propriétés de flèche. Les clés valides sont :
width: la largeur de la flèche en pointsfrac: la fraction de la longueur de la flèche occupée par la têteheadwidth: la largeur de la base de la tête de flèche en pointsshrink: déplacer l'extrémité et la base d'un certain pourcentage loin du point annoté et du texten'importe quelle clé pour matplotlib.patches.polygon(par exemple, facecolor)
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Ellipse
from matplotlib.text import OffsetFrom
## Créez notre figure et les données que nous utiliserons pour tracer
fig, ax = plt.subplots(figsize=(4, 4))
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
## Tracez une ligne et ajoutez quelques annotations simples
line, = ax.plot(t, s)
ax.annotate('pixels de figure',
xy=(10, 10), xycoords='pixels de figure')
ax.annotate('points de figure',
xy=(107, 110), xycoords='points de figure',
fontsize=12)
ax.annotate('fraction de figure',
xy=(.025,.975), xycoords='fraction de figure',
horizontalalignment='left', verticalalignment='top',
fontsize=20)
## Les exemples suivants montrent comment ces flèches sont dessinées.
ax.annotate('décalage de point à partir des données',
xy=(3, 1), xycoords='data',
xytext=(-10, 90), textcoords='points d'offset',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='center', verticalalignment='bottom')
ax.annotate('fraction d'axes',
xy=(2, 1), xycoords='data',
xytext=(0.36, 0.68), textcoords='fraction d'axes',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='right', verticalalignment='top')
## Vous pouvez également utiliser des points ou des pixels négatifs pour spécifier à partir de (droite, haut).
## Par exemple, (-10, 10) est 10 points à gauche du côté droit des axes et 10
## points au-dessus du bas
ax.annotate('décalage de pixel à partir de la fraction d'axes',
xy=(1, 0), xycoords='fraction d'axes',
xytext=(-20, 20), textcoords='pixels d'offset',
horizontalalignment='right',
verticalalignment='bottom')
ax.set(xlim=(-1, 5), ylim=(-3, 5))
Utilisation de multiples systèmes de coordonnées et de types d'axes
Vous pouvez spécifier le xypoint et le xytext dans des positions et des systèmes de coordonnées différents, et facultativement activer une ligne de connexion et marquer le point avec un marqueur. Les annotations fonctionnent également sur des axes polaires.
fig, ax = plt.subplots(subplot_kw=dict(projection='polar'), figsize=(3, 3))
r = np.arange(0, 1, 0.001)
theta = 2*2*np.pi*r
line, = ax.plot(theta, r)
ind = 800
thisr, thistheta = r[ind], theta[ind]
ax.plot([thistheta], [thisr], 'o')
ax.annotate('une annotation polaire',
xy=(thistheta, thisr), ## theta, rayon
xytext=(0.05, 0.05), ## fraction, fraction
textcoords='fraction de figure',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='left',
verticalalignment='bottom')
Personnalisation des styles de flèche et de bulle
La flèche entre xytext et le point d'annotation, ainsi que la bulle qui recouvre le texte d'annotation, sont hautement personnalisables. Voici quelques options de paramètres ainsi que leur résultat.
fig, ax = plt.subplots(figsize=(8, 5))
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=3)
ax.annotate(
'droite',
xy=(0, 1), xycoords='data',
xytext=(-50, 30), textcoords='points d\'offset',
arrowprops=dict(arrowstyle="->"))
ax.annotate(
'arc3,\nrad 0.2',
xy=(0.5, -1), xycoords='data',
xytext=(-80, -60), textcoords='points d\'offset',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3,rad=.2"))
ax.annotate(
'arc,\nangle 50',
xy=(1., 1), xycoords='data',
xytext=(-90, 50), textcoords='points d\'offset',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc,angleA=0,armA=50,rad=10"))
ax.annotate(
'arc,\nbras',
xy=(1.5, -1), xycoords='data',
xytext=(-80, -60), textcoords='points d\'offset',
arrowprops=dict(
arrowstyle="->",
connectionstyle="arc,angleA=0,armA=40,angleB=-90,armB=30,rad=7"))
ax.annotate(
'angle,\nangle 90',
xy=(2., 1), xycoords='data',
xytext=(-70, 30), textcoords='points d\'offset',
arrowprops=dict(arrowstyle="->",
connectionstyle="angle,angleA=0,angleB=90,rad=10"))
ax.annotate(
'angle3,\nangle -90',
xy=(2.5, -1), xycoords='data',
xytext=(-80, -60), textcoords='points d\'offset',
arrowprops=dict(arrowstyle="->",
connectionstyle="angle3,angleA=0,angleB=-90"))
ax.annotate(
'angle,\narrondi',
xy=(3., 1), xycoords='data',
xytext=(-60, 30), textcoords='points d\'offset',
bbox=dict(boxstyle="round", fc="0.8"),
arrowprops=dict(arrowstyle="->",
connectionstyle="angle,angleA=0,angleB=90,rad=10"))
ax.annotate(
'angle,\nround4',
xy=(3.5, -1), xycoords='data',
xytext=(-70, -80), textcoords='points d\'offset',
size=20,
bbox=dict(boxstyle="round4,pad=.5", fc="0.8"),
arrowprops=dict(arrowstyle="->",
connectionstyle="angle,angleA=0,angleB=-90,rad=10"))
ax.annotate(
'angle,\nrétrécissement',
xy=(4., 1), xycoords='data',
xytext=(-60, 30), textcoords='points d\'offset',
bbox=dict(boxstyle="round", fc="0.8"),
arrowprops=dict(arrowstyle="->",
shrinkA=0, shrinkB=10,
connectionstyle="angle,angleA=0,angleB=90,rad=10"))
## Vous pouvez passer une chaîne de caractères vide pour obtenir seulement les flèches d'annotation rendues
ax.annotate('', xy=(4., 1.), xycoords='data',
xytext=(4.5, -1), textcoords='data',
arrowprops=dict(arrowstyle="<->",
connectionstyle="bar",
ec="k",
shrinkA=5, shrinkB=5))
ax.set(xlim=(-1, 5), ylim=(-4, 3))
Plus d'exemples de systèmes de coordonnées
Voici quelques exemples supplémentaires de systèmes de coordonnées et de la manière dont la position des annotations peut être spécifiée.
fig, (ax1, ax2) = plt.subplots(1, 2)
bbox_args = dict(boxstyle="round", fc="0.8")
arrow_args = dict(arrowstyle="->")
## Ici, nous allons démontrer les limites du système de coordonnées et la manière dont
## nous plaçons le texte d'annotation.
ax1.annotate('fraction de figure : 0, 0', xy=(0, 0), xycoords='fraction de figure',
xytext=(20, 20), textcoords='points d\'offset',
ha="gauche", va="bas",
bbox=bbox_args,
arrowprops=arrow_args)
ax1.annotate('fraction de figure : 1, 1', xy=(1, 1), xycoords='fraction de figure',
xytext=(-20, -20), textcoords='points d\'offset',
ha="droite", va="haut",
bbox=bbox_args,
arrowprops=arrow_args)
ax1.annotate('fraction d\'axes : 0, 0', xy=(0, 0), xycoords='fraction d\'axes',
xytext=(20, 20), textcoords='points d\'offset',
ha="gauche", va="bas",
bbox=bbox_args,
arrowprops=arrow_args)
ax1.annotate('fraction d\'axes : 1, 1', xy=(1, 1), xycoords='fraction d\'axes',
xytext=(-20, -20), textcoords='points d\'offset',
ha="droite", va="haut",
bbox=bbox_args,
arrowprops=arrow_args)
## Il est également possible de générer des annotations déplaçables
an1 = ax1.annotate('Faites-moi glisser 1', xy=(.5,.7), xycoords='data',
ha="centre", va="centre",
bbox=bbox_args)
an2 = ax1.annotate('Faites-moi glisser 2', xy=(.5,.5), xycoords=an1,
xytext=(.5,.3), textcoords='fraction d\'axes',
ha="centre", va="centre",
bbox=bbox_args,
arrowprops=dict(patchB=an1.get_bbox_patch(),
connectionstyle="arc3,rad=0.2",
**arrow_args))
an1.draggable()
an2.draggable()
an3 = ax1.annotate('', xy=(.5,.5), xycoords=an2,
xytext=(.5,.5), textcoords=an1,
ha="centre", va="centre",
bbox=bbox_args,
arrowprops=dict(patchA=an1.get_bbox_patch(),
patchB=an2.get_bbox_patch(),
connectionstyle="arc3,rad=0.2",
**arrow_args))
## Enfin, nous allons montrer quelques annotations et positions plus complexes
text = ax2.annotate('xy=(0, 1)\nxycoords=("data", "fraction d\'axes")',
xy=(0, 1), xycoords=("data", 'fraction d\'axes'),
xytext=(0, -20), textcoords='points d\'offset',
ha="centre", va="haut",
bbox=bbox_args,
arrowprops=arrow_args)
ax2.annotate('xy=(0.5, 0)\nxycoords=artist',
xy=(0.5, 0.), xycoords=text,
xytext=(0, -20), textcoords='points d\'offset',
ha="centre", va="haut",
bbox=bbox_args,
arrowprops=arrow_args)
ax2.annotate('xy=(0.8, 0.5)\nxycoords=ax1.transData',
xy=(0.8, 0.5), xycoords=ax1.transData,
xytext=(10, 10),
textcoords=OffsetFrom(ax2.bbox, (0, 0), "points"),
ha="gauche", va="bas",
bbox=bbox_args,
arrowprops=arrow_args)
ax2.set(xlim=[-2, 2], ylim=[-2, 2])
Récapitulatif
Ce laboratoire a abordé les bases de l'annotation de graphes dans Matplotlib. Vous avez appris à spécifier les points d'annotation et de texte, à utiliser plusieurs systèmes de coordonnées et de types d'axes, à personnaliser les styles de flèches et de bulles, et de plus nombreux exemples de systèmes de coordonnées. Ces outils sont essentiels pour rendre les graphes plus visuellement attrayants et pour communiquer efficacement des informations.