Cambiar la frecuencia de ticks en el eje x o y

8 minutos de lectura

Avatar de usuario de Dax Feliz
dax feliz

Estoy tratando de arreglar cómo python traza mis datos. Decir:

x = [0,5,9,10,15]
y = [0,1,2,3,4]

matplotlib.pyplot.plot(x,y)
matplotlib.pyplot.show()

Los ticks del eje x se trazan en intervalos de 5. ¿Hay alguna manera de hacer que muestre intervalos de 1?

  • Pregunta estrechamente relacionada: stackoverflow.com/questions/6682784/… y una gran solución: pyplot.locator_params(nbins=4)

    – Dr. Jan-Philip Gehrcke

    08/04/2014 a las 11:49

avatar de usuario de unutbu
unutbu

Puede establecer explícitamente dónde desea marcar las marcas con plt.xticks:

plt.xticks(np.arange(min(x), max(x)+1, 1.0))

Por ejemplo,

import numpy as np
import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(np.arange(min(x), max(x)+1, 1.0))
plt.show()

(np.arange se usó en lugar de Python range función por si acaso min(x) y max(x) son flotantes en lugar de enteros.)


los plt.plot (o ax.plot) la función establecerá automáticamente el valor predeterminado x y y límites. Si desea mantener esos límites y simplemente cambiar el tamaño de paso de las marcas de verificación, entonces podría usar ax.get_xlim() para descubrir qué límites ya ha establecido Matplotlib.

start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, stepsize))

El formateador de ticks predeterminado debería hacer un trabajo decente al redondear los valores de ticks a un número razonable de dígitos significativos. Sin embargo, si desea tener más control sobre el formato, puede definir su propio formateador. Por ejemplo,

ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))

Aquí hay un ejemplo ejecutable:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, 0.712123))
ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
plt.show()

  • ¿No hay forma de que decida sus propios límites, pero simplemente cambie el tamaño del paso? ¡Este método no es muy bueno si el mínimo es algo así como 3523.232512!

    – Corvus

    1 oct 2013 a las 16:41

  • @Corone, Ha pasado un tiempo desde que me preguntó, pero publiqué una respuesta a continuación que permite controlar fácilmente el tamaño del paso sin dejar de usar la determinación automática de límites.

    – jthomas

    26 de marzo de 2016 a las 13:04

  • Tenga en cuenta que el +1 en plt.xticks(np.arange(min(x), max(x)+1, 1.0)) es necesario para mostrar la última marca de verificación.

    – Alex Willison

    19 mayo 2017 a las 15:23

  • Sí, np.arange(start, stop) genera valores en el medio abierto intervalo [start, stop), including start but excluding stop. So I used max(x)+1 to ensure that max(x) is included.

    – unutbu

    May 19, 2017 at 16:19

  • is there an equivalent for datetime e.g. plt.xticks(np.arange(min(dates), max(dates)+0.1,0.1) ? it seems to only plots the year

    – William Baker Morrison

    Jan 10, 2018 at 11:42


robochat's user avatar
robochat

Another approach is to set the axis locator:

import matplotlib.ticker as plticker

loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)

There are several different types of locator depending upon your needs.

Here is a full example:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker

x = [0,5,9,10,15]

y = [0,1,2,3,4]
fig, ax = plt.subplots() ax.plot(x,y) loc = plticker.MultipleLocator(base=1.0) # este localizador pone marcas a intervalos regulares ax.xaxis.set_major_locator(loc) plt.show()

  • Esto no funciona como se esperaba. Específicamente, cuando usa fechas, no usa las fechas apropiadas.

    – Chris Fonnebeck

    5 de febrero de 2014 a las 17:02

  • Cuando use fechas, debe usar los métodos en el módulo matplotlib.dates. Por ejemplo matplotlib.dates.AutoDateLocator()

    – robochat

    20 de marzo de 2014 a las 13:06


  • Funcionó como se esperaba para mí, con fechas. Esta solución es mucho más fácil que la aceptada.

    – Pablo Suau

    8 de julio de 2016 a las 13:58

  • Que hace base=1.0 realmente quiere decir/hacer?

    – Proyectos de la costa oeste

    23 de abril de 2020 a las 6:18

  • base=1.0 significa que habrá un localizador para cada número entero. La documentación dice que MultipleLocator “Set[s] una marca en cada múltiplo entero de una base dentro del intervalo de vista”. Entonces, si base = 2, habrá una marca para los números pares y creo que podría poner base = 2.5.

    – robochat

    29 de abril de 2020 a las 17:22


Me gusta esta solución (desde el Libro de recetas de trazado de Matplotlib):

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]

tick_spacing = 1

fig, ax = plt.subplots(1,1)
ax.plot(x,y)
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
plt.show()

Esta solución le brinda un control explícito del espaciado de ticks a través del número dado a ticker.MultipleLocater()permite la determinación automática de límites y es fácil de leer más tarde.

  • ¡Una forma de hacer esto sin calcular los ticks explícitamente!

    –Zelphir Kaltstahl

    31 de agosto de 2016 a las 9:48

  • Esta es la misma respuesta que esta. No tiene sentido agregar una respuesta idéntica dos años después.

    – La Importancia De Ser Ernesto

    23 de junio de 2017 a las 10:41

  • Buena atrapada. No los reconocí como iguales cuando publiqué la respuesta. Aún así, creo que esta presentación es un poco más fácil de entender.

    – jthomas

    23 de junio de 2017 a las 15:17

  • La referencia del libro en esta respuesta también proporciona una fuente útil para obtener más información.

    – Steven C. Howell

    16/04/2018 a las 19:50

  • Esta es la misma respuesta que la de robochat, que llegó tres años antes.

    – MERosa

    8 sep 2019 a las 14:38

En caso de que alguien esté interesado en una frase general, simplemente obtenga los ticks actuales y utilícelos para establecer los nuevos ticks muestreando cada dos ticks.

ax.set_xticks(ax.get_xticks()[::2])

avatar de usuario de cholgraf
Cholgraf

Esto es un poco raro, pero por mucho el ejemplo más limpio/más fácil de entender que he encontrado para hacer esto. Es de una respuesta en SO aquí:

¿La forma más limpia de ocultar cada enésima etiqueta de marca en la barra de colores matplotlib?

for label in ax.get_xticklabels()[::2]:
    label.set_visible(False)

Luego, puede recorrer las etiquetas configurándolas para que sean visibles o no, según la densidad que desee.

editar: tenga en cuenta que a veces matplotlib establece etiquetas == '', por lo que puede parecer que una etiqueta no está presente, cuando en realidad lo está y simplemente no muestra nada. Para asegurarse de que está recorriendo las etiquetas visibles reales, puede intentar:

visible_labels = [lab for lab in ax.get_xticklabels() if lab.get_visible() is True and lab.get_text() != '']
plt.setp(visible_labels[::2], visible=False)

  • Esta es la solución más simple y genérica. Un pequeño ajuste: por lo general ax.get_xticklabels()[1::2] son las etiquetas que se ocultarán.

    – jolvi

    22 de septiembre de 2015 a las 12:02

  • Esto no funciona con matplotlib.finance.candlestick2

    – BCR

    12 de febrero de 2016 a las 16:12

  • @BCR podría ser que algunas de las xticklabels estén configuradas para '' de modo que cuando los recorre, está haciendo invisibles las xticklabels que están vacías (lo que no tendría ningún efecto en la visualización, pero podría significar que no está extrayendo las etiquetas correctas). Tu podrías intentar: vis_labels = [label for label in ax.get_xticklabels() if label.get_visible() is True]; plt.setp(vis_labels[::2], visible==False)

    – Choldgraf

    15/02/2016 a las 19:57


Avatar de usuario de Gary Steele
gary acero

si solo desea establecer el espaciado en una simple línea con un mínimo de repetitivo:

plt.gca().xaxis.set_major_locator(plt.MultipleLocator(1))

también funciona fácilmente para garrapatas menores:

plt.gca().xaxis.set_minor_locator(plt.MultipleLocator(1))

un poco bocado, pero bastante compacto

  • Esta es la solución más simple y genérica. Un pequeño ajuste: por lo general ax.get_xticklabels()[1::2] son las etiquetas que se ocultarán.

    – jolvi

    22 de septiembre de 2015 a las 12:02

  • Esto no funciona con matplotlib.finance.candlestick2

    – BCR

    12 de febrero de 2016 a las 16:12

  • @BCR podría ser que algunas de las xticklabels estén configuradas para '' de modo que cuando los recorre, está haciendo invisibles las xticklabels que están vacías (lo que no tendría ningún efecto en la visualización, pero podría significar que no está extrayendo las etiquetas correctas). Tu podrías intentar: vis_labels = [label for label in ax.get_xticklabels() if label.get_visible() is True]; plt.setp(vis_labels[::2], visible==False)

    – Choldgraf

    15/02/2016 a las 19:57


Este es un tema antiguo, pero tropiezo con esto de vez en cuando e hice esta función. Es muy conveniente:

import matplotlib.pyplot as pp
import numpy as np

def resadjust(ax, xres=None, yres=None):
    """
    Send in an axis and I fix the resolution as desired.
    """

    if xres:
        start, stop = ax.get_xlim()
        ticks = np.arange(start, stop + xres, xres)
        ax.set_xticks(ticks)
    if yres:
        start, stop = ax.get_ylim()
        ticks = np.arange(start, stop + yres, yres)
        ax.set_yticks(ticks)

Una advertencia de controlar los ticks de esta manera es que uno ya no disfruta de la actualización automática interactiva de la escala máxima después de una línea agregada. Entonces hazlo

gca().set_ylim(top=new_top) # for example

y vuelva a ejecutar la función de reajuste.

¿Ha sido útil esta solución?