Texto en Matplotlib Parcelas #

Introducción al trazado y trabajo con texto en Matplotlib.

Matplotlib tiene un amplio soporte de texto, que incluye soporte para expresiones matemáticas, soporte de tipo verdadero para salidas vectoriales y ráster, texto separado por nueva línea con rotaciones arbitrarias y soporte Unicode.

Debido a que incorpora fuentes directamente en los documentos de salida, por ejemplo, para postscript o PDF, lo que ve en la pantalla es lo que obtiene en la copia impresa. La compatibilidad con FreeType produce fuentes antialiasing muy agradables, que se ven bien incluso en tamaños de trama pequeños. Matplotlib incluye el suyo propio (gracias a Paul Barrett), que implementa un algoritmo de búsqueda de fuentes matplotlib.font_managermultiplataforma compatible con W3C .

El usuario tiene un gran control sobre las propiedades del texto (tamaño de fuente, grosor de fuente, ubicación y color del texto, etc.) con valores predeterminados sensibles establecidos en el archivo rc . Y significativamente, para aquellos interesados ​​en figuras matemáticas o científicas, Matplotlib implementa una gran cantidad de símbolos y comandos matemáticos de TeX, que admiten expresiones matemáticas en cualquier parte de su figura.

Comandos de texto básicos #

Los siguientes comandos se utilizan para crear texto en las interfaces implícita y explícita (consulte Interfaces de aplicación (API) de Matplotlib para obtener una explicación de las ventajas y desventajas):

API implícita

API explícita

descripción

text

text

Agregue texto en una ubicación arbitraria del archivo Axes.

annotate

annotate

Agregue una anotación, con una flecha opcional, en una ubicación arbitraria del archivo Axes.

xlabel

set_xlabel

Agregue una etiqueta al Axeseje x de .

ylabel

set_ylabel

Agregue una etiqueta al Axeseje y de .

title

set_title

Agrega un título al Axes.

figtext

text

Agregue texto en una ubicación arbitraria del archivo Figure.

suptitle

suptitle

Agrega un título al Figure.

Todas estas funciones crean y devuelven una Textinstancia, que se puede configurar con una variedad de fuentes y otras propiedades. El siguiente ejemplo muestra todos estos comandos en acción, y se proporcionan más detalles en las secciones siguientes.

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()
subtítulo de figura en negrita, título de ejes

Etiquetas para los ejes x e y #

Especificar las etiquetas para los ejes x e y es sencillo mediante los métodos set_xlabely .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()
introducción de texto

Las etiquetas x e y se colocan automáticamente para borrar las etiquetas x e y. Compara la gráfica de abajo con la de arriba y observa que la etiqueta y está a la izquierda de la de arriba.

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()
introducción de texto

Si desea mover las etiquetas, puede especificar el argumento de palabra clave labelpad , donde el valor es puntos (1/72", la misma unidad utilizada para especificar tamaños de fuente).

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()
introducción de texto

O bien, las etiquetas aceptan todos los Textargumentos de palabras clave, incluida la posición , a través de la cual podemos especificar manualmente las posiciones de las etiquetas. Aquí colocamos la etiqueta x en el extremo izquierdo del eje. Tenga en cuenta que la coordenada y de esta posición no tiene efecto; para ajustar la posición y, necesitamos usar el argumento de palabra clave 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()
introducción de texto

Todo el etiquetado en este tutorial se puede cambiar manipulando el matplotlib.font_manager.FontPropertiesmétodo o mediante argumentos de palabras clave con nombre paraset_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()
introducción de texto

Finalmente, podemos usar la representación TeX nativa en todos los objetos de texto y tener varias líneas:

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()
introducción de texto

Títulos #

Los títulos de las subparcelas se establecen de la misma manera que las etiquetas, pero existen argumentos de palabra clave loc que pueden cambiar la posición y la justificación del valor predeterminado 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()
Título con ubicación en el centro Título con ubicación a la izquierda Título con ubicación a la derecha

El espaciado vertical de los títulos se controla mediante rcParams["axes.titlepad"](predeterminado: 6.0). El ajuste a un valor diferente mueve el título.

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()
Título desplazado verticalmente

Ticks y ticklabels #

Colocar ticks y ticklabels es un aspecto muy complicado de hacer una figura. Matplotlib hace todo lo posible para realizar la tarea automáticamente, pero también ofrece un marco muy flexible para determinar las opciones para las ubicaciones de las marcas y cómo se etiquetan.

Terminología #

Los ejes tienen un matplotlib.axis.Axisobjeto para el ax.xaxisy ax.yaxisque contienen la información sobre cómo se distribuyen las etiquetas en el eje.

La API del eje se explica en detalle en la documentación de axis.

Un objeto Axis tiene marcas mayores y menores. The Axis tiene métodos que utilizan los datos que se trazan para determinar la ubicación de los ticks principales y secundarios Axis.set_major_locator. Axis.set_minor_locatorTambién existen métodos Axis.set_major_formatterque dan Axis.set_minor_formatterformato a las etiquetas de marca.

Marcas simples #

A menudo es conveniente simplemente definir los valores de marca y, a veces, las etiquetas de marca, anulando los localizadores y formateadores predeterminados. Esto no se recomienda porque interrumpe la navegación interactiva de la trama. También puede restablecer los límites de los ejes: tenga en cuenta que la segunda gráfica tiene las marcas que solicitamos, incluidas las que están muy por fuera de los límites de vista automáticos.

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()
introducción de texto

Por supuesto, podemos arreglar esto después del hecho, pero resalta una debilidad de codificar los ticks. Este ejemplo también cambia el formato de los ticks:

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()
introducción de texto

Localizadores de ticks y formateadores #

En lugar de hacer una lista de todos los ticklabels, podríamos haber usado matplotlib.ticker.StrMethodFormatter(cadena de formato de estilo nuevo str.format() ) o matplotlib.ticker.FormatStrFormatter(cadena de formato '%' de estilo antiguo) y pasarlo al archivo ax.xaxis. A matplotlib.ticker.StrMethodFormattertambién se puede crear pasando a strsin tener que crear explícitamente el formateador.

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()
introducción de texto

Y, por supuesto, podríamos haber usado un localizador no predeterminado para establecer las ubicaciones de marca. Tenga en cuenta que aún pasamos los valores de marca, pero la corrección de límite x utilizada anteriormente no es necesaria.

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()
introducción de texto

El formateador predeterminado es matplotlib.ticker.MaxNLocatorllamado como La palabra clave steps contiene una lista de múltiplos que se pueden usar para valores de marca. es decir, en este caso, 2, 4, 6 serían ticks aceptables, al igual que 20, 40, 60 o 0,2, 0,4, 0,6. Sin embargo, 3, 6, 9 no serían aceptables porque 3 no aparece en la lista de pasos.ticker.MaxNLocator(self, nbins='auto', steps=[1, 2, 2.5, 5, 10])

nbins=autoutiliza un algoritmo para determinar cuántos ticks serán aceptables en función de la longitud del eje. Se tiene en cuenta el tamaño de fuente de la etiqueta de tick, pero no la longitud de la cadena de tick (porque aún no se conoce). En la fila inferior, las etiquetas de tick son bastante grandes, por lo que configuramos nbins=4para que las etiquetas encajen a la derecha . parcela de mano.

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()
introducción de texto

Finalmente, podemos especificar funciones para el formateador usando matplotlib.ticker.FuncFormatter. Además, como matplotlib.ticker.StrMethodFormatter, pasar una función creará automáticamente 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()
introducción de texto

Marcas de fecha #

Matplotlib puede aceptar datetime.datetimey numpy.datetime64 objetos como argumentos de trazado. Las fechas y horas requieren un formato especial, que a menudo puede beneficiarse de la intervención manual. Para ayudar, las fechas tienen localizadores y formateadores especiales, definidos en el matplotlib.datesmódulo.

Un ejemplo simple es el siguiente. Tenga en cuenta cómo tenemos que rotar las etiquetas de las marcas para que no se superpongan entre sí.

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()
introducción de texto

Podemos pasar un formato a matplotlib.dates.DateFormatter. También tenga en cuenta que el 29 y el próximo mes están muy juntos. Podemos arreglar esto usando la dates.DayLocatorclase, que nos permite especificar una lista de días del mes para usar. Los formateadores similares se enumeran en el matplotlib.dates módulo.

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()
introducción de texto

Leyendas y Anotaciones #

Tiempo total de ejecución del script: (0 minutos 5,998 segundos)

Galería generada por Sphinx-Gallery