Al hacer una gráfica semilogarítmica (y es log), las marcas de verificación menores (8 en una década) en el eje y aparecen automáticamente, pero parece que cuando el rango del eje supera 10**10, desaparecen. Intenté muchas maneras de obligarlos a volver a entrar, pero fue en vano. Puede ser que se vayan por grandes rangos para evitar el hacinamiento, pero ¿uno debería tener una opción?
Solución
solución para matplotlib >= 2.0.2
Consideremos el siguiente ejemplo
que es producido por este código:
import matplotlib.pyplot as plt
import matplotlib.ticker
import numpy as np
y = np.arange(12)
x = 10.0**y
fig, ax=plt.subplots()
ax.plot(x,y)
ax.set_xscale("log")
plt.show()
Las etiquetas de ticks menores han desaparecido y las formas habituales de mostrarlas (como ) fallan.plt.tick_params(axis='x', which='minor')
El primer paso sería entonces mostrar todas las potencias de 10 en el eje,
locmaj = matplotlib.ticker.LogLocator(base=10,numticks=12)
ax.xaxis.set_major_locator(locmaj)
donde el truco es establecer en un número igual o mayor el número de ticks (es decir, 12 o superior en este caso).numticks
Luego, podemos agregar ticklabels menores como
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(0.2,0.4,0.6,0.8),numticks=12)
ax.xaxis.set_minor_locator(locmin)
ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
Tenga en cuenta que restringí esto para incluir 4 garrapatas menores por década (usar 8 es igualmente posible, pero en este ejemplo abarrotaría los ejes). También tenga en cuenta que es de nuevo (bastante poco intuitivo) 12 o más.numticks
Finalmente necesitamos usar un para las garrapatas menores, para que no aparezcan etiquetas de garrapatas para ellas.NullFormatter()
solución para matplotlib 2.0.0
Lo siguiente funciona en matplotlib 2.0.0 o inferior, pero no funciona en matplotlib 2.0.2.
Consideremos el siguiente ejemplo
que es producido por este código:
import matplotlib.pyplot as plt
import matplotlib.ticker
import numpy as np
y = np.arange(12)
x = 10.0**y
fig, ax=plt.subplots()
ax.plot(x,y)
ax.set_xscale("log")
plt.show()
Las etiquetas de ticks menores han desaparecido y las formas habituales de mostrarlas (como ) fallan.plt.tick_params(axis='x', which='minor')
El primer paso sería entonces mostrar todas las potencias de 10 en el eje,
locmaj = matplotlib.ticker.LogLocator(base=10.0, subs=(0.1,1.0, ))
ax.xaxis.set_major_locator(locmaj)
Luego, podemos agregar ticklabels menores como
locmin = matplotlib.ticker.LogLocator(base=10.0, subs=(0.1,0.2,0.4,0.6,0.8,1,2,4,6,8,10 ))
ax.xaxis.set_minor_locator(locmin)
ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
Tenga en cuenta que restringí esto para incluir 4 garrapatas menores por década (usar 8 es igualmente posible, pero en este ejemplo abarrotaría los ejes). También tenga en cuenta – y esa puede ser la clave aquí – que el argumento, que da los múltiplos de potencias enteras de la base en la que colocar las marcas (ver documentación), se le da una lista que abarca más de dos décadas en lugar de una.subs
Finalmente necesitamos usar un para las garrapatas menores, para que no aparezcan etiquetas de garrapatas para ellas.NullFormatter()
Otras respuestas
Wrapping the excellent answer from importanceofbeingernest for into a function:matplotlib >= 2.0.2
import matplotlib.pyplot as plt
from typing import Optional
def restore_minor_ticks_log_plot(
ax: Optional[plt.Axes] = None, n_subticks=9
) -> None:
"""For axes with a logrithmic scale where the span (max-min) exceeds
10 orders of magnitude, matplotlib will not set logarithmic minor ticks.
If you don't like this, call this function to restore minor ticks.
Args:
ax:
n_subticks: Number of Should be either 4 or 9.
Returns:
None
"""
if ax is None:
ax = plt.gca()
# Method from SO user importanceofbeingernest at
# https://stackoverflow.com/a/44079725/5972175
locmaj = mpl.ticker.LogLocator(base=10, numticks=1000)
ax.xaxis.set_major_locator(locmaj)
locmin = mpl.ticker.LogLocator(
base=10.0, subs=np.linspace(0, 1.0, n_subticks + 2)[1:-1], numticks=1000
)
ax.xaxis.set_minor_locator(locmin)
ax.xaxis.set_minor_formatter(mpl.ticker.NullFormatter())
Esta función se puede llamar entonces como
plt.plot(x,y)
plt.xscale("log")
restore_minor_ticks_log_plot()
o más explícitamente
_, ax = plt.subplots()
ax.plot(x, y)
ax.set_xscale("log")
restore_minor_ticks_log_plot(ax)