I have a log-log plot and want to use sparse minor-tick labels using the minor_thresholds option of LogFormatter and, at the same time, avoid using scientific notation. My best attempt, using dummy data spanning the same range as my real data:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
x = np.array([1.2**e for e in range(-18, 13)])
y = 10 * x
plt.rcParams['axes.formatter.min_exponent'] = 3
fig = plt.figure()
ax = fig.add_subplot()
ax.scatter(x, y)
ax.set_xscale('log')
ax.set_yscale('log')
fmt = ticker.LogFormatter(labelOnlyBase=False, minor_thresholds=(3, 0.5))
ax.xaxis.set_minor_formatter(fmt)
ax.yaxis.set_minor_formatter(fmt)
This results in:
Good points:
- only a reasonable subset of minor ticks is labeled
- labels of the major ticks have the correct format (see '0.1')
Bad point:
- labels of the minor ticks still use scientific notation - it looks like it ignores the
axes.formatter.min_exponentoption
How can I fix it? (I would also like to avoid fixed notation that adds a decimal point for numbers that do not need it.)
Edit:
Based on @tmdavison's answer, I tried to make a version of his _num_to_string that would take into account axes.formatter.min_exponent. The simplest form would then be
def _num_to_string(self, x, vmin, vmax):
min_exp = mpl.rcParams['axes.formatter.min_exponent']
fx = math.log(x) / math.log(self._base)
if abs(fx) < min_exp:
return '%g' % x
else:
return self._pprint_val(x, vmax - vmin)
This is based on the assumption that _pprint_val would take care of the other cases, which is not correct - the only consideration _print_val has for x is that it uses %d if it is an integer below 1e4. Otherwise, it bases the formatting on the range (vmax - vmin) .. which seems principally wrong for a log-based axes.
Moreover, I observe a very strange behaviour with the above _num_to_string: the function gets called 168 times for each axis, even if it only prints 12 numbers. For example, for x-axis x has 28 values from 0.002 to 6000(!), and this sequence is called 6 times! There is surely a reason for this, but it surely looks weird...

