pythonmatplotlibplotgridlines

major gridlines with LogLocator behave incorrectly?


I am trying to mark the major gridlines of a semilogx plot with thicker lines. However, the code below (SSCCE) only highlights every second gridline.

import matplotlib.pyplot as plt
from matplotlib.ticker import (MultipleLocator, LogLocator)

# configuration
xValues = [0.1, 1, 10, 100, 1e3, 10e3, 100e3, 1e6, 10e6, 100e6]
yValues = [-70, -95,  -135, -165, -175, -180, -180, -180, -180, -180]

# plot 
fig = plt.figure(1, figsize=[10, 5], dpi=150)
ax = fig.subplots(1,1)

plt.semilogx(xValues, yValues)
plt.minorticks_on()

ax.yaxis.set_major_locator(MultipleLocator(10))
ax.yaxis.set_minor_locator(MultipleLocator(5))
ax.xaxis.set_major_locator(LogLocator(base=10.0))
ax.xaxis.set_minor_locator(LogLocator(base=10.0,subs=(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),numticks=72))

plt.grid(True, axis='both', which='major', linestyle="-", linewidth=0.8, color=(0.6, 0.6, 0.6))
plt.grid(True, axis='both', which='minor', linestyle="-", linewidth=0.5, color=(0.9, 0.9, 0.9))

plt.tight_layout()
plt.show()

Is there a good way to achieve what I want? (In the plot, you can see that the x axis only hightlights every second decade instead of every decade). Since the axis labels are also on different heights, I believe the reason is that the major gridlines are incorrect?

plot of code example above


Solution

  • It looks like the default numticks fails.

    numticks : None or int, default: None The maximum number of ticks to allow on a given axis. The default of None will try to choose intelligently as long as this Locator has already been assigned to an axis using ~.axis.Axis.get_tick_space, but otherwise falls back to 9.

    You can try to set a high number (100 or np.inf):

    ax.xaxis.set_major_locator(LogLocator(base=10.0, numticks=100))
    ax.xaxis.set_minor_locator(LogLocator(base=10.0, numticks=100),
                               subs=(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9))
    

    Or:

    ax.xaxis.set_major_locator(LogLocator(base=10.0, numticks=np.inf))
    ax.xaxis.set_minor_locator(LogLocator(base=10.0, numticks=np.inf), 
                               subs=(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9))
    

    enter image description here