HOWTO · Matplotlib

Cómo girar el texto de la etiqueta de la marca del eje X en Matplotlib

Aprenda cinco formas de girar las etiquetas de las marcas del eje x en Matplotlib y de alinearlas cuando las etiquetas largas se superponen.

En esta página

Para girar las etiquetas de las marcas del eje x en Matplotlib, pasa un ángulo como rotation=45 a plt.xticks, fig.autofmt_xdate, ax.set_xticklabels, plt.setp o ax.tick_params. Un ángulo de 45 grados es un buen punto de partida cuando las etiquetas horizontales largas se superponen; alinea las etiquetas giradas con ha="right" para que sus extremos queden cerca de las marcas. En los ejemplos siguientes se indica cuándo conviene usar cada API.

Sin rotación, los nombres de categoría, como los meses, se colocan en horizontal y ocupan todo el ancho del eje, por lo que los nombres más largos o una figura más estrecha hacen que las etiquetas vecinas se junten:

Gráfico de líneas de valores mensuales con etiquetas horizontales January, February, March y April que ocupan todo el ancho del eje.

Girar las etiquetas de las marcas del eje x con plt.xticks

plt.xticks es una opción concisa para trabajar con pyplot. Su argumento rotation establece el ángulo en grados; de forma predeterminada, las etiquetas son horizontales. Este ejemplo representa varias categorías y gira sus etiquetas 45 grados.

import matplotlib.pyplot as plt

months = ["January", "February", "March", "April"]
values = [12, 18, 15, 22]

fig, ax = plt.subplots()
ax.plot(months, values, marker="o")
plt.xticks(rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

El mismo gráfico de líneas mensual con las etiquetas giradas 45 grados y alineadas a la derecha, de modo que cada etiqueta termina en su marca.

Usa plt.xticks para hacer un cambio rápido en los ejes actuales. Si tu código ya utiliza un objeto Axes, los métodos de los apartados siguientes permiten especificar directamente a qué ejes se aplica el cambio.

Girar las etiquetas del eje de fechas con fig.autofmt_xdate

En los gráficos orientados a fechas, fig.autofmt_xdate da formato a las etiquetas de fecha de la figura y las gira para facilitar su lectura. De forma predeterminada, también ajusta la alineación y el margen inferior; puedes indicar rotation explícitamente si quieres un ángulo concreto. El comportamiento depende de los ejes de la figura y del formato de fecha, así que úsalo con ejes de fechas, no como sustituto general de cualquier ajuste de las etiquetas de las marcas.

import matplotlib.pyplot as plt
from datetime import date, timedelta

start = date(2024, 1, 1)
dates = [start + timedelta(days=7 * i) for i in range(6)]
values = [3, 5, 4, 7, 6, 9]

fig, ax = plt.subplots()
ax.plot(dates, values, marker="o")
fig.autofmt_xdate(rotation=45)
ax.grid(True)

Gráfico de líneas con seis fechas semanales de enero y febrero de 2024 y las etiquetas de fecha giradas 45 grados mediante autofmt_xdate.

Esta opción resulta práctica cuando el eje x representa fechas y es necesario girar y espaciar sus etiquetas formateadas. Para categorías normales, elige uno de los métodos de etiquetas de las marcas de los otros apartados.

Definir las etiquetas y su giro con ax.set_xticklabels

Usa ax.set_xticklabels si necesitas proporcionar texto personalizado para las etiquetas, además de definir su giro. Primero establece explícitamente las posiciones de las marcas y luego proporciona una etiqueta para cada posición, de modo que cada texto corresponda a la marca prevista. Girar las etiquetas no requiere reemplazarlas: usa tick_params o plt.setp para conservar el texto existente.

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["North region", "South region", "East region", "West region"]
values = [8, 5, 9, 6]

fig, ax = plt.subplots()
ax.plot(positions, values, marker="o")
ax.set_xticks(positions)
ax.set_xticklabels(labels, rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

Gráfico de líneas con etiquetas personalizadas North region, South region, East region y West region giradas 45 grados y alineadas a la derecha.

Mantén las posiciones y las etiquetas en el mismo orden. Si más adelante cambian las marcas del gráfico, actualiza las etiquetas personalizadas para que correspondan a ellas.

Definir las propiedades de las etiquetas con plt.setp

plt.setp actualiza las propiedades de los artistas existentes de Matplotlib, incluidos los objetos actuales de las etiquetas de las marcas del eje x que devuelve ax.get_xticklabels(). Es útil cuando las etiquetas ya están definidas y solo quieres cambiar su aspecto.

import matplotlib.pyplot as plt

categories = ["First quarter", "Second quarter", "Third quarter", "Fourth quarter"]
values = [14, 17, 13, 21]

fig, ax = plt.subplots()
ax.plot(categories, values, marker="o")
plt.setp(ax.get_xticklabels(), rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

Gráfico de líneas de valores trimestrales con las etiquetas giradas 45 grados y alineadas a la derecha mediante plt.setp.

En este caso, rotation cambia el ángulo y ha establece la alineación horizontal. Así se actualizan los objetos actuales de las etiquetas de las marcas sin reemplazar su texto.

Definir el giro de las etiquetas del eje x con ax.tick_params

ax.tick_params establece las propiedades de las marcas, sus etiquetas y las líneas de la cuadrícula para el eje elegido. Pasa axis="x" y el argumento en minúsculas labelrotation para girar las etiquetas del eje x sin cambiar su texto ni sus posiciones.

import matplotlib.pyplot as plt

categories = ["Planning", "Development", "Review", "Delivery"]
values = [2, 5, 3, 6]

fig, ax = plt.subplots()
ax.plot(categories, values, marker="o")
ax.tick_params(axis="x", labelrotation=45)
ax.grid(True)
fig.tight_layout()

Gráfico de líneas de cuatro fases de proyecto con las etiquetas giradas 45 grados mediante la palabra clave labelrotation de tick_params.

Usa esta forma a nivel de eje cuando ya tengas una referencia a Axes. El argumento se escribe labelrotation, todo en minúsculas.

Alinear las etiquetas de las marcas giradas

El giro cambia el ángulo, mientras que la alineación horizontal determina qué parte de cada etiqueta coincide con su marca. Con ha="right", el extremo derecho de la etiqueta coincide con la marca; con ha="left", coincide el extremo izquierdo; y con ha="center", coincide el centro. Para etiquetas giradas 45 grados que se extienden hacia la izquierda de sus marcas, la alineación a la derecha suele ser una opción adecuada. Prueba las opciones teniendo en cuenta la longitud de las etiquetas y la disposición del gráfico.

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["January", "February", "March", "April"]
values = [4, 7, 5, 8]
alignments = ["right", "left", "center"]

fig, axes = plt.subplots(1, 3, figsize=(10, 3))
for ax, alignment in zip(axes, alignments):
    ax.plot(positions, values, marker="o")
    ax.set_xticks(positions)
    ax.set_xticklabels(labels, rotation=45, ha=alignment)
    ax.set_title(f'ha="{alignment}"')
    ax.grid(True)
fig.tight_layout()

Tres gráficos de líneas en paralelo que comparan etiquetas a 45 grados con alineación horizontal right, left y center.

Elige la alineación según el punto en el que quieras anclar cada etiqueta. Si siguen viéndose amontonadas, además de girarlas, ajusta el ancho de la figura o acorta el texto de las etiquetas.

Resolver etiquetas recortadas y errores de cantidad de etiquetas

Quedan dos fallos posibles aun cuando la rotación funciona. Primero, ax.set_xticklabels sustituye el texto de las etiquetas, por lo que la cantidad de etiquetas debe coincidir con la cantidad de posiciones de marca. Pasar tres etiquetas para cuatro posiciones hace que la llamada falle antes de dibujar nada:

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["North", "South", "East"]
values = [8, 5, 9, 6]

fig, ax = plt.subplots()
ax.plot(positions, values, marker="o")
ax.set_xticks(positions)
ax.set_xticklabels(labels, rotation=45, ha="right")

La llamada termina con este error:

ValueError: The number of FixedLocator locations (4), usually from a call to set_ticks, does not match the number of labels (3).

Añada la etiqueta que falta para que ambas secuencias tengan la misma longitud y el mismo orden. Si solo necesita girar el texto existente, prefiera plt.setp o ax.tick_params: conservan las etiquetas actuales, por lo que esta discrepancia no puede producirse.

Segundo, la rotación cambia el ángulo, pero no crea espacio debajo del eje. Renderice el ejemplo de set_xticklabels anterior sin su llamada a fig.tight_layout() y las etiquetas giradas sobrepasarán el borde inferior de la figura: en una renderización de tamaño predeterminado se extienden unos 31 píxeles más allá del borde y quedan cortadas a mitad del texto:

Gráfico de líneas con etiquetas de región a 45 grados recortadas en el borde inferior de la figura porque no se aplicó tight_layout.

fig.tight_layout() recalcula el marco de la figura para que cada etiqueta quepa; medido de la misma manera, las etiquetas terminan entonces exactamente en el borde de la figura, sin nada fuera de ella. fig.autofmt_xdate realiza un ajuste de margen equivalente para los ejes de fecha. Si las etiquetas siguen chocando tras el ajuste de diseño, acorte el texto de las etiquetas o ensanche la figura en lugar de aumentar el ángulo.