23

Does anyone know how to show the labels of the minor ticks on a logarithmic scale with Python/Matplotlib?

Georgy
  • 12,464
  • 7
  • 65
  • 73
Tomas
  • 503
  • 2
  • 7
  • 15
  • Have you look at function [set_tick_params()](http://matplotlib.org/api/axis_api.html)? The doc says : _Set appearance parameters for ticks and ticklabels._ – prodev_paris Jun 17 '15 at 11:03
  • This question seems to be a duplicate of http://stackoverflow.com/questions/17165435/matplotlib-show-labels-for-minor-ticks-also/17167748#17167748 – prodev_paris Jun 17 '15 at 12:06
  • In case someone is looking for a solution to show minor ticks on a log axis which ranges over more than 10 decades, the below solution would not work and one may have a look at [this question](http://stackoverflow.com/questions/44078409/matplolib-semi-log-plot-minor-tick-marks-are-gone-when-range-is-large) instead. – ImportanceOfBeingErnest May 19 '17 at 22:18

2 Answers2

21

You can use plt.tick_params(axis='y', which='minor') to set the minor ticks on and format them with the matplotlib.ticker FormatStrFormatter. For example,

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FormatStrFormatter
x = np.linspace(0,4,1000)
y = np.exp(x)
plt.plot(x, y)
ax = plt.gca()
ax.set_yscale('log')
plt.tick_params(axis='y', which='minor')
ax.yaxis.set_minor_formatter(FormatStrFormatter("%.1f"))
plt.show()

enter image description here

xnx
  • 24,509
  • 11
  • 70
  • 109
  • I thinks the OP was asking more in the sense he wants some label on minor ticks. Like in this related answer : http://stackoverflow.com/a/17167748/4716013 – prodev_paris Jun 17 '15 at 12:03
  • @prodev_paris -- you're right: I've edited my answer to make it more complete. – xnx Jun 17 '15 at 13:31
  • 1
    @xnx is there a way to label every _n_ th minor tick? for example something like `plt.tick_params(axis='x', which='minor', every=6)` – 3kstc Jul 07 '17 at 04:45
  • Even better, turn on the grid! – Bill N Sep 27 '17 at 17:21
12

One option is to use matplotlib.ticker.LogLocator

import numpy
import pylab
import matplotlib.pyplot
import matplotlib.ticker
## setup styles
from  matplotlib import rc
rc('font', **{'family': 'sans-serif', 'sans-serif': ['Times-Roman']})
rc('text', usetex = True)
matplotlib.rcParams['text.latex.preamble'] = [r"\usepackage{amsmath}"]

## make figure
figure, ax = matplotlib.pyplot.subplots(1, sharex = True, squeeze = True)
x = numpy.linspace(0.0, 20.0, 1000)
y = numpy.exp(x)
ax.plot(x, y)
ax.set_yscale('log')

## set y ticks
y_major = matplotlib.ticker.LogLocator(base = 10.0, numticks = 5)
ax.yaxis.set_major_locator(y_major)
y_minor = matplotlib.ticker.LogLocator(base = 10.0, subs = numpy.arange(1.0, 10.0) * 0.1, numticks = 10)
ax.yaxis.set_minor_locator(y_minor)
ax.yaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())

## save figure
pylab.tight_layout()
pylab.savefig('./test.png', dpi = 200)

you would get

minor ticks

the only thing you need to manually adjust is the numticks input for both major and minor ticks, they both have to be a fraction of total possible number of major ticks.

zyy
  • 1,271
  • 15
  • 25
  • 1
    this worked for me, just had a similar issue here https://stackoverflow.com/questions/65727726/matplotlib-add-gridlines-not-working-as-expected? – a11 Jan 15 '21 at 00:13