Rotar etiquetas de marca de eje

4 minutos de lectura

Avatar de usuario de tMC
TMC

No puedo entender cómo rotar el texto en el eje X. Es una marca de tiempo, por lo que a medida que aumenta el número de muestras, se acercan más y más hasta que se superponen. Me gustaría rotar el texto 90 grados para que las muestras no se superpongan a medida que se acerquen.

A continuación se muestra lo que tengo, funciona bien con la excepción de que no puedo descifrar cómo rotar el texto del eje X.

import sys

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import datetime

font = {'family' : 'normal',
        'weight' : 'bold',
        'size'   : 8}

matplotlib.rc('font', **font)

values = open('stats.csv', 'r').readlines()

time = [datetime.datetime.fromtimestamp(float(i.split(',')[0].strip())) for i in values[1:]]
delay = [float(i.split(',')[1].strip()) for i in values[1:]]

plt.plot(time, delay)
plt.grid(b='on')

plt.savefig('test.png')

Esto funciona para mí:

plt.xticks(rotation=90)

avatar de usuario de getup8
vestir8

Muchas respuestas “correctas” aquí, pero agregaré una más ya que creo que algunos detalles quedan fuera de varias. El OP solicitó una rotación de 90 grados, pero cambiaré a 45 grados porque cuando usa un ángulo que no es cero o 90, también debe cambiar la alineación horizontal; de lo contrario, sus etiquetas estarán descentradas y un poco engañosas (y supongo que muchas personas que vienen aquí quieren rotar los ejes a algo más que 90).

Código más fácil / mínimo

Opción 1

plt.xticks(rotation=45, ha="right")

Como se mencionó anteriormente, eso puede no ser deseable si prefiere adoptar el enfoque orientado a objetos.

opcion 2

Otra forma rápida (está diseñada para objetos de fecha pero parece funcionar en cualquier etiqueta; sin embargo, dudo que se recomiende):

fig.autofmt_xdate(rotation=45)

fig normalmente obtendrías de:

  • fig = plt.gcf()
  • fig = plt.figure()
  • fig, ax = plt.subplots()
  • fig = ax.figure

Orientado a objetos / Tratar directamente con ax

Opción 3a

Si tienes la lista de etiquetas:

labels = ['One', 'Two', 'Three']
ax.set_xticks([1, 2, 3])
ax.set_xticklabels(labels, rotation=45, ha="right")

En versiones posteriores de Matplotlib (3.5+), solo puede usar set_xticks solo:

ax.set_xticks([1, 2, 3], labels, rotation=45, ha="right")

Opción 3b

Si desea obtener la lista de etiquetas de la trama actual:

# Unfortunately you need to draw your figure first to assign the labels,
# otherwise get_xticklabels() will return empty strings.
plt.draw()
ax.set_xticks(ax.get_xticks())
ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha="right")

Como arriba, en versiones posteriores de Matplotlib (3.5+), solo puede usar set_xticks solo:

ax.set_xticks(ax.get_xticks(), ax.get_xticklabels(), rotation=45, ha="right")

Opción 4

Similar al anterior, pero en su lugar recorre manualmente.

for label in ax.get_xticklabels():
  label.set_rotation(45)
  label.set_ha('right')

Opción 5

todavía usamos pyplot (como plt) aquí pero está orientado a objetos porque estamos cambiando la propiedad de un objeto específico ax objeto.

plt.setp(ax.get_xticklabels(), rotation=45, ha="right")

Opción 6

Esta opción es simple, pero AFAIK no puede configurar la alineación horizontal de la etiqueta de esta manera, por lo que otra opción podría ser mejor si su ángulo no es 90.

ax.tick_params(axis="x", labelrotation=45)

Editar:
Hay una discusión sobre este “error” exacto, pero no se ha publicado una solución (a partir de 3.4.0):
https://github.com/matplotlib/matplotlib/issues/13774

avatar de usuario de ryanjdillon
ryanjdillon

Camino fácil

Como descrito aquíexiste un método en el matplotlib.pyplot figure clase que rota automáticamente las fechas de manera apropiada para su figura.

Puede llamarlo después de trazar sus datos (es decir,ax.plot(dates,ydata) :

fig.autofmt_xdate()

Si necesita formatear más las etiquetas, consulte el enlace anterior.

Objetos sin fecha y hora

según languitarracomentario de , el método que sugerí para non-datetime xticks no se actualizaría correctamente al hacer zoom, etc. Si no es un datetime objeto utilizado como datos del eje x, debe seguir tommyrespuesta de:

for tick in ax.get_xticklabels():
    tick.set_rotation(45)

avatar de usuario de opiethehokie
opiethehokie

Pruebe pyplot.setp. Creo que podrías hacer algo como esto:

x = range(len(time))
plt.xticks(x,  time)
locs, labels = plt.xticks()
plt.setp(labels, rotation=90)
plt.plot(x, delay)

Aparte de

plt.xticks(rotation=90)

esto también es posible:

plt.xticks(rotation='vertical')

avatar de usuario de cjohnson318
cjohnson318

Se me ocurrió un ejemplo similar. Una vez más, la palabra clave de rotación es… bueno, es clave.

from pylab import *
fig = figure()
ax = fig.add_subplot(111)
ax.bar( [0,1,2], [1,3,5] )
ax.set_xticks( [ 0.5, 1.5, 2.5 ] )
ax.set_xticklabels( ['tom','dick','harry'], rotation=45 ) ;

avatar de usuario de kiril
kiril

Si desea aplicar rotación en el objeto de ejes, la forma más fácil es usar tick_params. Por ejemplo.

ax.tick_params(axis="x", labelrotation=90)

Referencia de la documentación de Matplotlib aquí.

Esto es útil cuando tiene una matriz de ejes devuelta por plt.subplotsy es más conveniente que usar set_xticks porque en ese caso también debe establecer las etiquetas de marca, y también es más conveniente que aquellas que iteran sobre las marcas (por razones obvias)

¿Ha sido útil esta solución?