Annotation #

Annotation de texte avec Matplotlib.

from matplotlib import pyplot as plt

Annotation de base #

Les utilisations de la base text()placeront le texte à une position arbitraire sur les Axes. Un cas d'utilisation courant du texte consiste à annoter certaines caractéristiques du tracé, et la annotate()méthode fournit une fonctionnalité d'assistance pour faciliter les annotations. Dans une annotation, il y a deux points à considérer : l'emplacement annoté représenté par l'argument xy et l'emplacement du texte xytext . Ces deux arguments sont des tuples.(x, y)

../../_images/sphx_glr_annotation_basic_001.png

Dans cet exemple, les emplacements xy (pointe de flèche) et xytext (emplacement du texte) sont en coordonnées de données. Il existe une variété d'autres systèmes de coordonnées que l'on peut choisir - 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 (la valeur par défaut est 'data')

dispute

système de coordonnées

'points de chiffres'

points du coin inférieur gauche de la figure

'chiffre pixels'

pixels du coin inférieur gauche de la figure

'fraction de chiffres'

(0, 0) est en bas à gauche de la figure et (1, 1) est en haut à droite

'points d'axes'

points du coin inférieur gauche des axes

'axes pixels'

pixels du coin inférieur gauche des axes

'fraction d'axes'

(0, 0) est en bas à gauche des axes et (1, 1) est en haut à droite

'Les données'

utiliser le système de coordonnées des données des axes

Par exemple pour placer les coordonnées du texte en coordonnées d'axes fractionnaires, on pourrait faire :

ax.annotate('local max', xy=(3, 1),  xycoords='data',
            xytext=(0.8, 0.95), textcoords='axes fraction',
            arrowprops=dict(facecolor='black', shrink=0.05),
            horizontalalignment='right', verticalalignment='top',
            )

Pour les systèmes de coordonnées physiques (points ou pixels), l'origine est le coin inférieur gauche de la figure ou des axes.

Facultativement, vous pouvez activer le dessin d'une flèche du texte au point annoté en donnant un dictionnaire des propriétés de la flèche dans l'argument mot-clé facultatif arrowprops .

clé d'accessoires de flèche

la description

largeur

la largeur de la flèche en points

frac

la fraction de la longueur de la flèche occupée par la tête

largeur de tête

la largeur de la base de la tête de flèche en points

rétrécir

éloignez la pointe et la base de quelques pour cent du point et du texte annotés

**kwargs

n'importe quelle clé pour matplotlib.patches.Polygon, par exemple,facecolor

Dans l'exemple ci-dessous, le point xy est en coordonnées natives ( xycoords par défaut est 'data'). Pour un axe polaire, c'est dans l'espace (thêta, rayon). Le texte de cet exemple est placé dans le système de coordonnées des chiffres fractionnaires. matplotlib.text.Text les arguments de mot-clé comme horizontalalignment , verticalalignment et fontsize sont passés de annotateà l' Textinstance.

../../_images/sphx_glr_annotation_polar_001.png

Pour en savoir plus sur toutes les choses folles et merveilleuses que vous pouvez faire avec les annotations, y compris les flèches fantaisie, voir Annotations avancées et annotation de tracés .

Ne continuez que si vous avez déjà lu l' annotation de base text()et annotate()!

Annotations avancées #

Annoter avec du texte avec Box #

Commençons par un exemple simple.

../../_images/sphx_glr_annotate_text_arrow_001.png

textprend un argument de mot-clé bbox , qui dessine une boîte autour du texte :

t = ax.text(
    0, 0, "Direction", ha="center", va="center", rotation=45, size=15,
    bbox=dict(boxstyle="rarrow,pad=0.3", fc="cyan", ec="b", lw=2))

L'objet patch associé au texte est accessible par :

bb = t.get_bbox_patch()

La valeur de retour est un FancyBboxPatch; les propriétés du patch (facecolor, edgewidth, etc.) peuvent être consultées et modifiées comme d'habitude. FancyBboxPatch.set_boxstyledéfinit la forme de la boîte :

bb.set_boxstyle("rarrow", pad=0.6)

Les arguments sont le nom du style de boîte avec ses attributs comme arguments de mots-clés. Actuellement, les styles de boîte suivants sont implémentés.

Classer

Nom

Attrs

Cercle

circle

pad=0.3

DFlèche

darrow

pad=0.3

LA Flèche

larrow

pad=0.3

RFlèche

rarrow

pad=0.3

Tour

round

pad=0.3,rounding_size=Aucun

Tour4

round4

pad=0.3,rounding_size=Aucun

Dent ronde

roundtooth

pad=0.3,tooth_size=Aucun

Dent de scie

sawtooth

pad=0.3,tooth_size=Aucun

Carré

square

pad=0.3

../../_images/sphx_glr_fancybox_demo_001.png

Notez que les arguments d'attribut peuvent être spécifiés dans le nom du style avec une virgule de séparation (cette forme peut être utilisée comme valeur "boxstyle" de l'argument bbox lors de l'initialisation de l'instance de texte)

bb.set_boxstyle("rarrow,pad=0.6")

Annoter avec la flèche #

annotatedessine une flèche reliant deux points dans un Axes :

ax.annotate("Annotation",
            xy=(x1, y1), xycoords='data',
            xytext=(x2, y2), textcoords='offset points',
            )

Cela annote un point à xy dans la coordonnée donnée ( xycoords ) avec le texte à xytext donné dans textcoords . Souvent, le point annoté est spécifié dans les coordonnées des données et le texte d'annotation dans les points de décalage . Voir annotatepour les systèmes de coordonnées disponibles.

Une flèche reliant xy à xytext peut éventuellement être dessinée en spécifiant l' argument arrowprops . Pour dessiner uniquement une flèche, utilisez une chaîne vide comme premier argument.

ax.annotate("",
            xy=(0.2, 0.2), xycoords='data',
            xytext=(0.8, 0.8), textcoords='data',
            arrowprops=dict(arrowstyle="->",
                            connectionstyle="arc3"),
            )
../../_images/sphx_glr_annotate_simple01_001.png

La flèche est tracée comme suit :

  1. Un chemin reliant les deux points est créé, comme spécifié par le paramètre connectionstyle .

  2. Le chemin est coupé pour éviter les patchs patchA et patchB , s'ils sont définis.

  3. Le chemin est encore rétréci par rétrécissementA et rétrécissementB (en pixels).

  4. Le chemin est transmuté en patch de flèche, comme spécifié par le paramètre arrowstyle .

../../_images/sphx_glr_annotate_explain_001.png

La création du chemin de connexion entre deux points est contrôlée par connectionstyleclé et les styles suivants sont disponibles.

Nom

Attrs

angle

angleA=90,angleB=0,rad=0.0

angle3

angleA=90,angleB=0

arc

angleA=0,angleB=0,brasA=Aucun,brasB=Aucun,rad=0.0

arc3

rad=0.0

bar

brasA=0.0,brasB=0.0,fraction=0.3,angle=Aucun

Notez que "3" dans angle3et arc3est destiné à indiquer que le chemin résultant est un segment de spline quadratique (trois points de contrôle). Comme nous le verrons ci-dessous, certaines options de style de flèche ne peuvent être utilisées que lorsque le chemin de connexion est une spline quadratique.

Le comportement de chaque style de connexion est (limité) démontré dans l'exemple ci-dessous. (Attention : Le comportement du barstyle n'est actuellement pas bien défini, il pourra être modifié dans le futur).

../../_images/sphx_glr_connectionstyle_demo_001.png

Le chemin de connexion (après découpage et rétrécissement) est ensuite muté en un patch de flèche, selon le arrowstyle.

Nom

Attrs

-

Aucun

->

head_length=0.4,head_width=0.2

-[

largeurB=1.0,longueurB=0.2,angleB=Aucun

|-|

largeurA=1.0,largeurB=1.0

-|>

head_length=0.4,head_width=0.2

<-

head_length=0.4,head_width=0.2

<->

head_length=0.4,head_width=0.2

<|-

head_length=0.4,head_width=0.2

<|-|>

head_length=0.4,head_width=0.2

fancy

head_length=0.4,head_width=0.4,tail_width=0.4

simple

head_length=0.5,head_width=0.5,tail_width=0.2

wedge

tail_width=0.3,shrink_factor=0.5

../../_images/sphx_glr_fancyarrow_demo_001.png

Certains styles de flèche ne fonctionnent qu'avec des styles de connexion qui génèrent un segment de spline quadratique. Ce sont fancy, simpleet wedge. Pour ces styles de flèche, vous devez utiliser le style de connexion "angle3" ou "arc3".

Si la chaîne d'annotation est donnée, le patchA est défini sur le patch bbox du texte par défaut.

../../_images/sphx_glr_annotate_simple02_001.png

Comme avec text, une boîte autour du texte peut être dessinée en utilisant l' argument bbox .

../../_images/sphx_glr_annotate_simple03_001.png

Par défaut, le point de départ est défini au centre de l'étendue du texte. Ceci peut être ajusté avec relposla valeur clé. Les valeurs sont normalisées à l'étendue du texte. Par exemple, (0, 0) signifie coin inférieur gauche et (1, 1) signifie coin supérieur droit.

../../_images/sphx_glr_annotate_simple04_001.png

Placer l'artiste aux emplacements Axes ancrés #

Il existe des classes d'artistes qui peuvent être placées à un emplacement ancré dans les Axes. Un exemple courant est la légende. Ce type d'artiste peut être créé en utilisant la OffsetBoxclasse. Quelques classes prédéfinies sont disponibles dans matplotlib.offsetboxet dans mpl_toolkits.axes_grid1.anchored_artists.

from matplotlib.offsetbox import AnchoredText

fig, ax = plt.subplots()
at = AnchoredText(
    "Figure 1a", prop=dict(size=15), frameon=True, loc='upper left')
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
annotations
<matplotlib.offsetbox.AnchoredText object at 0x7f2cdd7d9cf0>

Le mot-clé loc a la même signification que dans la commande legend.

Une application simple est lorsque la taille de l'artiste (ou de la collection d'artistes) est connue en taille de pixel au moment de la création. Par exemple, si vous souhaitez dessiner un cercle de taille fixe de 20 pixels x 20 pixels (rayon = 10 pixels), vous pouvez utiliser AnchoredDrawingArea. L'instance est créée avec une taille de la zone de dessin (en pixels), et des artistes arbitraires peuvent être ajoutés à la zone de dessin. Notez que l'étendue des artistes ajoutés à la zone de dessin n'est pas liée au placement de la zone de dessin elle-même. Seule la taille initiale compte.

Les artistes ajoutés à la zone de dessin ne doivent pas avoir de jeu de transformation (il sera remplacé) et les dimensions de ces artistes sont interprétées comme une coordonnée de pixels, c'est-à-dire que le rayon des cercles dans l'exemple ci-dessus est de 10 pixels et 5 pixels , respectivement.

from matplotlib.patches import Circle
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredDrawingArea

fig, ax = plt.subplots()
ada = AnchoredDrawingArea(40, 20, 0, 0,
                          loc='upper right', pad=0., frameon=False)
p1 = Circle((10, 10), 10)
ada.drawing_area.add_artist(p1)
p2 = Circle((30, 10), 5, fc="r")
ada.drawing_area.add_artist(p2)
ax.add_artist(ada)
annotations
<mpl_toolkits.axes_grid1.anchored_artists.AnchoredDrawingArea object at 0x7f2cde0e07f0>

Parfois, vous souhaitez que vos artistes soient mis à l'échelle avec les coordonnées des données (ou des coordonnées autres que les pixels du canevas). Vous pouvez utiliser AnchoredAuxTransformBoxla classe. Ceci est similaire à AnchoredDrawingAreasauf que l'étendue de l'artiste est déterminée pendant le temps de dessin en respectant la transformation spécifiée.

L'ellipse dans l'exemple ci-dessous aura une largeur et une hauteur correspondant à 0,1 et 0,4 en coordonnées de données et sera automatiquement mise à l'échelle lorsque les limites de vue des axes changent.

from matplotlib.patches import Ellipse
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredAuxTransformBox

fig, ax = plt.subplots()
box = AnchoredAuxTransformBox(ax.transData, loc='upper left')
el = Ellipse((0, 0), width=0.1, height=0.4, angle=30)  # in data coordinates!
box.drawing_area.add_artist(el)
ax.add_artist(box)
annotations
<mpl_toolkits.axes_grid1.anchored_artists.AnchoredAuxTransformBox object at 0x7f2cde48dea0>

Comme dans la légende, l'argument bbox_to_anchor peut être défini. En utilisant HPacker et VPacker, vous pouvez avoir un arrangement (?) d'artiste comme dans la légende (en fait, c'est ainsi que la légende est créée).

../../_images/sphx_glr_anchored_box04_001.png

Notez que contrairement à la légende, le bbox_transformest défini sur IdentityTransform par défaut.

Systèmes de coordonnées pour les annotations #

Les annotations Matplotlib prennent en charge plusieurs types de coordonnées. Certains sont décrits dans Annotation de base ; des options plus avancées sont

  1. Un Transformexemple. Par exemple,

    ax.annotate("Test", xy=(0.5, 0.5), xycoords=ax.transAxes)
    

    est identique à

    ax.annotate("Test", xy=(0.5, 0.5), xycoords="axes fraction")
    

    Cela permet d'annoter un point dans un autre axe :

    fig, (ax1, ax2) = plt.subplots(1, 2)
    ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData,
                 xytext=(0.5, 0.5), textcoords=ax2.transData,
                 arrowprops=dict(arrowstyle="->"))
    
  2. Un Artistexemple. La valeur xy (ou xytext ) est interprétée comme une coordonnée fractionnaire de la bbox (valeur de retour de get_window_extent ) de l'artiste :

    an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data",
                      va="center", ha="center",
                      bbox=dict(boxstyle="round", fc="w"))
    an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1,  # (1, 0.5) of the an1's bbox
                      xytext=(30, 0), textcoords="offset points",
                      va="center", ha="left",
                      bbox=dict(boxstyle="round", fc="w"),
                      arrowprops=dict(arrowstyle="->"))
    
    ../../_images/sphx_glr_annotate_simple_coord01_001.png

    Notez que vous devez vous assurer que l'étendue de l'artiste de coordonnées ( an1 dans l'exemple ci-dessus) est déterminée avant que an2 ne soit dessiné. Habituellement, cela signifie que an2 doit être dessiné après an1 .

  3. Un objet appelable qui prend l'instance de moteur de rendu comme argument unique et renvoie soit a, Transformsoit a BboxBase. La valeur de retour est alors traitée comme dans (1), pour les transformations, ou dans (2), pour les bboxes. Par exemple,

    an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1,
                      xytext=(30, 0), textcoords="offset points")
    

    est identique à :

    an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1.get_window_extent,
                      xytext=(30, 0), textcoords="offset points")
    
  4. Une paire de spécifications de coordonnées -- la première pour la coordonnée x et la seconde pour la coordonnée y ; par exemple

    annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction"))
    

    Ici, 0,5 est en coordonnées de données et 1 en coordonnées d'axes normalisés. Chacune des spécifications de coordonnées peut également être un artiste ou une transformation. Par exemple,

    ../../_images/sphx_glr_annotate_simple_coord02_001.png
  5. Parfois, vous souhaitez que votre annotation comporte des "points décalés", non pas à partir du point annoté mais à partir d'un autre point. text.OffsetFromest une aide pour de tels cas.

    ../../_images/sphx_glr_annotate_simple_coord03_001.png

    Vous pouvez jeter un œil à cet exemple Annotating Plots .

Utilisation de ConnectionPatch #

ConnectionPatchest comme une annotation sans texte. S'il annotate est suffisant dans la plupart des situations, ConnectionPatchil est utile lorsque vous souhaitez connecter des points sur des axes différents.

from matplotlib.patches import ConnectionPatch
xy = (0.2, 0.2)
con = ConnectionPatch(xyA=xy, coordsA=ax1.transData,
                      xyB=xy, coordsB=ax2.transData)
fig.add_artist(con)

Le code ci-dessus relie le point xy dans les coordonnées de données de ax1au point xy dans les coordonnées de données de ax2. Voici un exemple simple.

../../_images/sphx_glr_connect_simple01_001.png

Ici, nous avons ajouté le ConnectionPatchà la figure (avec add_artist) plutôt qu'à l'un ou l'autre des axes : cela garantit qu'il est dessiné au-dessus des deux axes, et est également nécessaire si vous utilisez Constrained_layout pour positionner les axes.

Sujets avancés #

Effet Zoom entre Axes #

mpl_toolkits.axes_grid1.inset_locatordéfinit certaines classes de patch utiles pour interconnecter deux axes. Comprendre le code nécessite une certaine connaissance du système de transformation de Matplotlib.

../../_images/sphx_glr_axes_zoom_effect_001.png

Définir le style de boîte personnalisé #

Vous pouvez utiliser un style de boîte personnalisé. La valeur de boxstylepeut être un objet appelable sous les formes suivantes :

def __call__(self, x0, y0, width, height, mutation_size,
             aspect_ratio=1.):
    '''
    Given the location and size of the box, return the path of
    the box around it.

      - *x0*, *y0*, *width*, *height* : location and size of the box
      - *mutation_size* : a reference scale for the mutation.
      - *aspect_ratio* : aspect-ratio for the mutation.
    '''
    path = ...
    return path

Voici un exemple complet.

../../_images/sphx_glr_custom_boxstyle01_001.png

De même, vous pouvez définir un ConnectionStyle personnalisé et un ArrowStyle personnalisé. Consultez le code source de lib/matplotlib/patches.pyet vérifiez comment chaque classe de style est définie.

Galerie générée par Sphinx-Gallery