Texte dans les tracés Matplotlib #

Introduction au traçage et à l'utilisation de texte dans Matplotlib.

Matplotlib a une prise en charge étendue du texte, y compris la prise en charge des expressions mathématiques, la prise en charge du type vrai pour les sorties raster et vectorielles, le texte séparé par une nouvelle ligne avec des rotations arbitraires et la prise en charge d'Unicode.

Parce qu'il intègre les polices directement dans les documents de sortie, par exemple, pour le postscript ou le PDF, ce que vous voyez à l'écran est ce que vous obtenez sur la copie papier. La prise en charge de FreeType produit de très belles polices anticrénelées, qui ont fière allure même avec de petites tailles de raster. Matplotlib inclut le sien (grâce à Paul Barrett), qui implémente un algorithme de recherche de polices matplotlib.font_managermultiplateforme conforme au W3C .

L'utilisateur a un grand contrôle sur les propriétés du texte (taille de la police, poids de la police, emplacement et couleur du texte, etc.) avec des valeurs par défaut raisonnables définies dans le fichier rc . Et de manière significative, pour ceux qui s'intéressent aux figures mathématiques ou scientifiques, Matplotlib implémente un grand nombre de symboles et de commandes mathématiques TeX, prenant en charge les expressions mathématiques n'importe où dans votre figure.

Commandes textuelles de base #

Les commandes suivantes sont utilisées pour créer du texte dans les interfaces implicites et explicites (voir Interfaces d'application Matplotlib (API) pour une explication des compromis) :

API implicite

API explicite

la description

text

text

Ajoutez du texte à un emplacement arbitraire du fichier Axes.

annotate

annotate

Ajoutez une annotation, avec une flèche facultative, à un emplacement arbitraire du fichier Axes.

xlabel

set_xlabel

Ajoutez une étiquette à l' Axesaxe des abscisses.

ylabel

set_ylabel

Ajoutez une étiquette à l' Axesaxe y de .

title

set_title

Ajoutez un titre au Axes.

figtext

text

Ajoutez du texte à un emplacement arbitraire du fichier Figure.

suptitle

suptitle

Ajoutez un titre au Figure.

Toutes ces fonctions créent et renvoient une Textinstance, qui peut être configurée avec une variété de polices et d'autres propriétés. L'exemple ci-dessous montre toutes ces commandes en action, et plus de détails sont fournis dans les sections qui suivent.

import matplotlib
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot()
fig.subplots_adjust(top=0.85)

# Set titles for the figure and the subplot respectively
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold')
ax.set_title('axes title')

ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')

# Set both x- and y-axis limits to [0, 10] instead of default [0, 1]
ax.axis([0, 10, 0, 10])

ax.text(3, 8, 'boxed italics text in data coords', style='italic',
        bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})

ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15)

ax.text(3, 2, 'Unicode: Institut für Festkörperphysik')

ax.text(0.95, 0.01, 'colored text in axes coords',
        verticalalignment='bottom', horizontalalignment='right',
        transform=ax.transAxes,
        color='green', fontsize=15)

ax.plot([2], [1], 'o')
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),
            arrowprops=dict(facecolor='black', shrink=0.05))

plt.show()
suptitle en gras, titre des axes

Étiquettes pour les axes x et y #

La spécification des étiquettes pour les axes x et y est simple, via les méthodes set_xlabelet .set_ylabel

import matplotlib.pyplot as plt
import numpy as np

x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)

fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]')

plt.show()
introduction de texte

Les étiquettes x et y sont automatiquement placées de sorte qu'elles effacent les étiquettes x et y. Comparez le tracé ci-dessous avec celui ci-dessus et notez que l'étiquette y est à gauche de celle ci-dessus.

fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]')

plt.show()
introduction de texte

Si vous souhaitez déplacer les étiquettes, vous pouvez spécifier l' argument du mot-clé labelpad , où la valeur est en points (1/72", la même unité utilisée pour spécifier les tailles de police).

fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]', labelpad=18)

plt.show()
introduction de texte

Ou bien, les étiquettes acceptent tous les Textarguments de mots-clés, y compris position , via lesquels nous pouvons spécifier manuellement les positions des étiquettes. Ici, nous plaçons le xlabel à l'extrême gauche de l'axe. Notez que la coordonnée y de cette position n'a aucun effet - pour ajuster la position y, nous devons utiliser l' argument du mot-clé labelpad .

fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', position=(0., 1e6), horizontalalignment='left')
ax.set_ylabel('Damped oscillation [V]')

plt.show()
introduction de texte

Tous les étiquetages de ce didacticiel peuvent être modifiés en manipulant la matplotlib.font_manager.FontPropertiesméthode ou en utilisant des arguments de mots clés nommés pourset_xlabel

from matplotlib.font_manager import FontProperties

font = FontProperties()
font.set_family('serif')
font.set_name('Times New Roman')
font.set_style('italic')

fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', fontsize='large', fontweight='bold')
ax.set_ylabel('Damped oscillation [V]', fontproperties=font)

plt.show()
introduction de texte

Enfin, nous pouvons utiliser le rendu natif TeX dans tous les objets texte et avoir plusieurs lignes :

fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.2, left=0.2)
ax.plot(x1, np.cumsum(y1**2))
ax.set_xlabel('time [s] \n This was a long experiment')
ax.set_ylabel(r'$\int\ Y^2\ dt\ \ [V^2 s]$')
plt.show()
introduction de texte

Titres #

Les titres des sous-parcelles sont définis de la même manière que les étiquettes, mais il existe les arguments du mot-clé loc qui peuvent modifier la position et la justification par rapport à la valeur par défaut de loc=center.

fig, axs = plt.subplots(3, 1, figsize=(5, 6), tight_layout=True)
locs = ['center', 'left', 'right']
for ax, loc in zip(axs, locs):
    ax.plot(x1, y1)
    ax.set_title('Title with loc at '+loc, loc=loc)
plt.show()
Titre avec loc au centre, Titre avec loc à gauche, Titre avec loc à droite

L'espacement vertical des titres est contrôlé via rcParams["axes.titlepad"](par défaut : 6.0). Le réglage sur une valeur différente déplace le titre.

fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(top=0.8)
ax.plot(x1, y1)
ax.set_title('Vertically offset title', pad=30)
plt.show()
Titre décalé verticalement

Tiques et étiquettes de tiques #

Placer des ticks et des ticklabels est un aspect très délicat de la création d'une figure. Matplotlib fait de son mieux pour accomplir la tâche automatiquement, mais il offre également un cadre très flexible pour déterminer les choix d'emplacement des ticks et la manière dont ils sont étiquetés.

Terminologie #

Les axes ont un matplotlib.axis.Axisobjet pour ax.xaxiset ax.yaxisqui contient les informations sur la façon dont les étiquettes de l'axe sont disposées.

L'API de l'axe est expliquée en détail dans la documentation de axis.

Un objet Axis a des graduations majeures et mineures. L'Axe a Axis.set_major_locatoret des Axis.set_minor_locatorméthodes qui utilisent les données tracées pour déterminer l'emplacement des graduations majeures et mineures. Il existe également des méthodes Axis.set_major_formatteret Axis.set_minor_formatterqui formatent les étiquettes de coche.

Coches simples #

Il est souvent pratique de définir simplement les valeurs de graduation, et parfois les étiquettes de graduation, en remplaçant les localisateurs et les formateurs par défaut. Ceci est déconseillé car cela interrompt la navigation interactive de l'intrigue. Il peut également réinitialiser les limites de l'axe : notez que le deuxième tracé contient les graduations que nous avons demandées, y compris celles qui sont bien en dehors des limites de la vue automatique.

fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
axs[1].xaxis.set_ticks(np.arange(0., 8.1, 2.))
plt.show()
introduction de texte

Nous pouvons bien sûr résoudre ce problème après coup, mais cela met en évidence une faiblesse du codage en dur des ticks. Cet exemple modifie également le format des graduations :

fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
# list comprehension to get all tick labels...
tickla = [f'{tick:1.2f}' for tick in ticks]
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_ticklabels(tickla)
axs[1].set_xlim(axs[0].get_xlim())
plt.show()
introduction de texte

Localisateurs de tiques et formateurs #

Au lieu de faire une liste de tous les ticklabels, nous aurions pu utiliser matplotlib.ticker.StrMethodFormatter(nouvelle str.format() chaîne de format de style) ou matplotlib.ticker.FormatStrFormatter(ancienne chaîne de format '%') et la transmettre au fichier ax.xaxis. A matplotlib.ticker.StrMethodFormatterpeut également être créé en passant a strsans avoir à créer explicitement le formateur.

fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_major_formatter('{x:1.1f}')
axs[1].set_xlim(axs[0].get_xlim())
plt.show()
introduction de texte

Et bien sûr, nous aurions pu utiliser un localisateur autre que celui par défaut pour définir les emplacements des ticks. Notez que nous transmettons toujours les valeurs de tick, mais le correctif de limite x utilisé ci-dessus n'est pas nécessaire.

fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
locator = matplotlib.ticker.FixedLocator(ticks)
axs[1].xaxis.set_major_locator(locator)
axs[1].xaxis.set_major_formatter({x}°')
plt.show()
introduction de texte

Le formateur par défaut est matplotlib.ticker.MaxNLocatorappelé as Le mot-clé steps contient une liste de multiples qui peuvent être utilisés pour les valeurs de graduation. c'est-à-dire que dans ce cas, 2, 4, 6 seraient des coches acceptables, tout comme 20, 40, 60 ou 0,2, 0,4, 0,6. Cependant, 3, 6, 9 ne seraient pas acceptables car 3 n'apparaît pas dans la liste des étapes.ticker.MaxNLocator(self, nbins='auto', steps=[1, 2, 2.5, 5, 10])

nbins=autoutilise un algorithme pour déterminer combien de graduations seront acceptables en fonction de la longueur de l'axe. nbins=4La taille de police du ticklabel est prise en compte, mais la longueur de la chaîne de tick ne l'est pas (car elle n'est pas encore connue.) parcelle de main.

fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
    ax.plot(x1*10., y1)

formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
locator = matplotlib.ticker.MaxNLocator(nbins='auto', steps=[1, 4, 10])
axs[0, 1].xaxis.set_major_locator(locator)
axs[0, 1].xaxis.set_major_formatter(formatter)

formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.AutoLocator()
axs[1, 0].xaxis.set_major_formatter(formatter)
axs[1, 0].xaxis.set_major_locator(locator)

formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.MaxNLocator(nbins=4)
axs[1, 1].xaxis.set_major_formatter(formatter)
axs[1, 1].xaxis.set_major_locator(locator)

plt.show()
introduction de texte

Enfin, nous pouvons spécifier des fonctions pour le formateur en utilisant matplotlib.ticker.FuncFormatter. De plus, comme matplotlib.ticker.StrMethodFormatter, passer une fonction créera automatiquement un matplotlib.ticker.FuncFormatter.

def formatoddticks(x, pos):
    """Format odd tick positions."""
    if x % 2:
        return f'{x:1.2f}'
    else:
        return ''


fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.plot(x1, y1)
locator = matplotlib.ticker.MaxNLocator(nbins=6)
ax.xaxis.set_major_formatter(formatoddticks)
ax.xaxis.set_major_locator(locator)

plt.show()
introduction de texte

Datetic #

Matplotlib peut accepter datetime.datetimeet numpy.datetime64 des objets comme arguments de traçage. Les dates et les heures nécessitent un formatage spécial, qui peut souvent bénéficier d'une intervention manuelle. Pour vous aider, les dates ont des localisateurs et des formateurs spéciaux, définis dans le matplotlib.datesmodule.

Un exemple simple est le suivant. Notez comment nous devons faire pivoter les étiquettes de graduation afin qu'elles ne se chevauchent pas.

import datetime

fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]

ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()
introduction de texte

Nous pouvons passer un format à matplotlib.dates.DateFormatter. Notez également que le 29 et le mois suivant sont très rapprochés. Nous pouvons résoudre ce problème en utilisant la dates.DayLocatorclasse, qui nous permet de spécifier une liste de jours du mois à utiliser. Des formateurs similaires sont répertoriés dans le matplotlib.dates module.

import matplotlib.dates as mdates

locator = mdates.DayLocator(bymonthday=[1, 15])
formatter = mdates.DateFormatter('%b %d')

fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()
introduction de texte

Légendes et annotations #

Durée totale d'exécution du script : (0 minutes 5,998 secondes)

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