Diagrama semilogarítmico de Matplotlib: las marcas de verificación menores desaparecen cuando el rango es grande

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?

Respuestas:4 Respuestas 4
Tiempo:hace 5 años, 4 meses
Última modificación:hace 2 meses

Solución

solución para matplotlib >= 2.0.2

Consideremos el siguiente ejemplo

enter image description here

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)

enter image description here

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())

enter image description here

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

enter image description here

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)

enter image description here

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())

enter image description here

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)

Deja un comentario