xticks xlabel with outside graficos found example python matplotlib label

python - xlabel - ¿Cómo mover la etiqueta de una garrapata en matplotlib?



set xlabel matplotlib (4)

Me gustaría mover las etiquetas de algunos ticks horizontalmente a lo largo del eje x, sin mover los ticks correspondientes.

Más específicamente, al rotar etiquetas con plt.setp , los centros del texto de las etiquetas permanecen alineados con las marcas. Me gustaría mover esas etiquetas a la derecha, para que los extremos cercanos de las etiquetas se alineen como se sugiere en la imagen de abajo.

Estoy al tanto de esta publicación y esta , sin embargo, las respuestas son más interesantes que las respuestas estrictas a la pregunta.

mi código:

import matplotlib.pyplot as plt import numpy as np import datetime # my fake data dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365*5)]) data = np.sin(np.arange(365*5)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365*5) /3 # creates fig with 2 subplots fig = plt.figure(figsize=(10.0, 6.0)) ax = plt.subplot2grid((2,1), (0, 0)) ax2 = plt.subplot2grid((2,1), (1, 0)) ## plot dates ax2.plot_date( dates, data ) # rotates labels plt.setp( ax2.xaxis.get_majorticklabels(), rotation=-45 ) # try to shift labels to the right ax2.xaxis.get_majorticklabels()[2].set_y(-.1) ax2.xaxis.get_majorticklabels()[2].set_x(10**99) plt.show()

Por extraño que parezca, set_y comporta como se esperaba, pero incluso si configuro x en un fantasillion, las etiquetas no se moverían en una iota. (El uso de plot_date puede introducir confusión adicional, pero lo mismo sucede con plot ).


En lugar de

ax2.xaxis.get_majorticklabels()[2].set_y(-.1) ax2.xaxis.get_majorticklabels()[2].set_x(10**99)

use set_horizontalalignment() para cada tick en el eje:

for tick in ax2.xaxis.get_majorticklabels(): tick.set_horizontalalignment("left")

Resultando en:


En primer lugar, usemos un mcve para mostrar el problema.

import numpy as np import datetime import matplotlib.pyplot as plt plt.rcParams["date.autoformatter.month"] = "%b %Y" # my fake data dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365)]) data = np.sin(np.arange(365)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365) /3 # creates fig with 2 subplots fig, ax = plt.subplots(figsize=(6,2)) ## plot dates ax.plot_date( dates, data ) # rotates labels plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45 ) plt.tight_layout() plt.show()

Ahora, como ya han indicado otras respuestas, puede utilizar la alineación horizontal del texto.

# rotates labels and aligns them horizontally to left plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left" )

Puede usar el argumento rotation_mode para permitir que se produzca la rotación en el punto superior izquierdo del texto, dando un resultado ligeramente mejor en este caso.

# rotates labels and aligns them horizontally to left plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left", rotation_mode="anchor")

En caso de que esas opciones no sean lo suficientemente detalladas, es decir, si desea ubicar las etiquetas con mayor precisión, por ejemplo, desplazándolas hacia un lado en algunos puntos, puede usar una transformación. Lo siguiente compensaría la etiqueta en 5 puntos en dirección horizontal, utilizando un matplotlib.transforms.ScaledTranslation .

import matplotlib.transforms plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45) # Create offset transform by 5 points in x direction dx = 5/72.; dy = 0/72. offset = matplotlib.transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans) # apply offset transform to all x ticklabels. for label in ax.xaxis.get_majorticklabels(): label.set_transform(label.get_transform() + offset)

La ventaja de esto, en comparación con, por ejemplo, la solución provista por @explorerDude es que el desplazamiento es independiente de los datos en el gráfico, de modo que generalmente es aplicable a cualquier gráfico y se vería igual para un tamaño de fuente determinado.


Encontré una manera de cambiar las etiquetas de garrapatas del eje x en una cantidad arbitraria y exacta, pero de esta manera corre peligrosamente cerca de los acantilados escarpados y resbaladizos que se elevan sobre el mar de la locura. Así que solo los muy valientes o desesperados deberían seguir leyendo ...

Dicho esto, el problema es que la posición x de las etiquetas se establece cuando se representa el dibujo (no he buscado en esa parte del código, pero es mi entendimiento). Así que todo lo que haces con set_x () se anula más tarde. Sin embargo, hay una forma de evitarlo: puede crear un parche set_x para ciertos ticks para que las etiquetas no se dibujen donde el renderizador quiera dibujarlos:

import types SHIFT = 10. # Data coordinates for label in ax2.xaxis.get_majorticklabels(): label.customShiftValue = SHIFT label.set_x = types.MethodType( lambda self, x: matplotlib.text.Text.set_x(self, x-self.customShiftValue ), label, matplotlib.text.Text )

Puede hacerlo de forma selectiva solo para las etiquetas que desea cambiar y, por supuesto, también puede utilizar un turno diferente para cada etiqueta.

Si alguien sabe cómo hacer esto en un nivel de locura inferior, estaría muy interesado ...


Otra forma de hacer una alineación horizontal:

plt.xticks(ha=''left'')