Reducción del número de marcas de trama

160

Tengo demasiados ticks en mi gráfico y se están cruzando.

¿Cómo puedo reducir la cantidad de garrapatas?

Por ejemplo, tengo garrapatas:

1E-6, 1E-5, 1E-4, ... 1E6, 1E7

Y solo quiero:

1E-5, 1E-3, ... 1E5, 1E7

He intentado jugar con el LogLocator, pero no he podido resolver esto.

jlconlin
fuente

Respuestas:

266

Alternativamente, si desea establecer simplemente el número de ticks mientras permite que matplotlib los coloque (actualmente solo con MaxNLocator), haypyplot.locator_params ,

pyplot.locator_params(nbins=4)

Puede especificar un eje específico en este método como se menciona a continuación, el valor predeterminado es ambos:

# To specify the number of ticks on both or any single axes
pyplot.locator_params(axis='y', nbins=6)
pyplot.locator_params(axis='x', nbins=10)
bgamari
fuente
27
Esta fue una gran sugerencia, también poder especificar pyplot.locator_params(axis = 'x', nbins = 4)(o axis = 'y') hacer que el proceso sea realmente sencillo. Gracias @bgamari!
benjaminmgross
8
Con la escala logarítmica, esto funcionó en numtickslugar denbins
meduz
1
@bgamari, ¿podría agregar la numtickssolución para los gráficos logarítmicos como señala @meduz?
Løiten
77
Esto no parece colocar las etiquetas donde deberían estar. Por ejemplo, si las etiquetas de marca originales son [0, 1, ..., 99]y ahora se establece una nticks=10, entonces las nuevas etiquetas dispersas se colocarán separadas diez veces más a lo largo del eje, es decir, ahora 1se ubicarán donde 9estaba, 2dónde 19estaba ... y 9dónde 99estaba.
Vim
2
Verifique sus resultados antes de confiar en este método. @Vim es correcto. Los valores de marca se colocarán incorrectamente.
David J.
54

Si alguien aún obtiene esta página en los resultados de búsqueda:

fig, ax = plt.subplots()

plt.plot(...)

every_nth = 4
for n, label in enumerate(ax.xaxis.get_ticklabels()):
    if n % every_nth != 0:
        label.set_visible(False)
Katerina
fuente
77
Esto realmente funcionó frente a todas las otras respuestas que no hicieron nada. gracias :)
faizan
Bien hecho. Me tomó un tiempo encontrar esto, pero hizo lo que quería.
John
Gracias, esto asegura que las etiquetas restantes estén en las posiciones correctas. Un paso adicional que mejoraría esta respuesta es eliminar también la marca de verificación.
David J.
Gran respuesta simple: no sorprendió ningún método personalizado conocido por la comunidad SO. Esta sería una valiosa adición a lib?
jabberwocky
32

Para resolver el problema de la personalización y la apariencia de las garrapatas, consulte el guía de Localizadores de garrapatas en el sitio web matplotlib

ax.xaxis.set_major_locator(plt.MaxNLocator(3))

Establecería el número total de ticks en el eje x en 3, y lo distribuiría uniformemente a través del eje.

También hay un buen tutorial sobre esto

Prageeth Jayathissa
fuente
Solo seleccione los primeros 3 índices de fecha y hora. cuando obtenga el hacha de pandas.DataFrame.plot ax = df.plot()
Mithril el
@ Mitril lo siento, no entiendo tu comentario. ¿Podría por favor elaborar?
Prageeth Jayathissa el
Si tengo un df ( pandas.DataFrame) con índice de fecha y hora [2019-01-01, ... 2019-11-01], llame ax = df.plot(), devuelva un objeto de figura. la llamada ax.xaxis.set_major_locator(plt.MaxNLocator(3)) solo muestra los primeros 3 índices [2019-01-01, 2019-01-02, 2019-01-03].
Mithril el
1
@Mithril, a df.plot()menudo muestra el minor_locator, por lo que es posible que desee probar ax1.xaxis.set_minor_locator(plt.MaxNLocator(3)). También recuerde sustituir el 3número de ticks que desea mostrar. Para pandas timeseries recomiendo import matplotlib.dates as mdatesy correr ax.xaxis.set_minor_locator(mdates.MonthLocator(interval = 1))conax.xaxis.set_minor_formatter(mdates.DateFormatter('%m-%Y'))
Prageeth Jayathissa
20

Hay una set_ticks()función para los objetos del eje.

André Caron
fuente
44
Esto funcionaría si supiera de antemano qué garrapatas quería. El ejemplo que di arriba fue solo un ejemplo. No sé cuáles son las garrapatas, solo sé que quiero menos, es decir, todas las demás.
jlconlin
10
Puede llamar get_xticks()o get_yticks()primero para el objeto ejes, editar según sea necesario y luego pasar la lista nuevamente set_ticks().
user812786
44
No tengo set_ticks(), pero tengo set_xticks()y set_yticks(). Estos son atributos de objetos de ejes, no ejes. Tal vez esto ha cambiado durante los últimos años.
Gauthier
2
No estoy seguro de si debería hacerlo, algunas personas han encontrado su respuesta útil tal como es, y solo porque sea diferente para mí no significa que sea para todos.
Gauthier
1
Un ejemplo sería de gran ayuda para que esta respuesta sea útil.
Richard
10

en caso de que alguien aún lo necesite, y dado que nada aquí realmente funcionó para mí, se me ocurrió una forma muy simple que mantiene la apariencia de la trama generada "tal cual" mientras fija el número de tics exactamente N:

import numpy as np
import matplotlib.pyplot as plt

f, ax = plt.subplots()
ax.plot(range(100))

ymin, ymax = ax.get_ylim()
ax.set_yticks(np.round(np.linspace(ymin, ymax, N), 2))
Rafael
fuente
2
Tuve que modificar ligeramente la última línea para que devolviera los valores como int en lugar de flotante:ax.set_yticks(np.linspace(int(ymin), int(ymax), N), 2)
Nick Settje
@NickSettje todavía flota conmigo!
Mohd
4

La solución que dio @raphael es sencilla y bastante útil.

Aún así, las etiquetas de marca mostradas no serán valores muestreados de la distribución original sino de los índices de la matriz devueltos por np.linspace(ymin, ymax, N).

Para mostrar los valores de N espaciados uniformemente de sus etiquetas de marca original, utilice el set_yticklabels()método Aquí hay un fragmento para el eje y, con etiquetas enteras:

import numpy as np
import matplotlib.pyplot as plt

ax = plt.gca()

ymin, ymax = ax.get_ylim()
custom_ticks = np.linspace(ymin, ymax, N, dtype=int)
ax.set_yticks(custom_ticks)
ax.set_yticklabels(custom_ticks)
Tantris
fuente
Felicitaciones por este bonito ajuste!
Mohd
2

Cuando se usa una escala logarítmica, el número de tics principales se puede arreglar con el siguiente comando

import matplotlib.pyplot as plt

....

plt.locator_params(numticks=12)
plt.show()

El valor establecido en numticksdetermina el número de marcas de eje que se mostrarán.

Créditos a la publicación de @ bgamari para introducir la locator_params()función, pero el nticksparámetro arroja un error cuando se usa una escala logarítmica.

Ébe Isaac
fuente
La pregunta y la respuesta son para matplotlib anterior, es decir, 1, y se refiere a 2.
Dawid Laszuk