I really would like to have consistently $\cdot$ instead of $\times$ for the scientific notation in matplotlib. In addition I would like to keep all of the default settings of the matplotlib.ticker.ScalarFormatter, like the calculation of offsets. For this reason I cannot simply create a new formatter with FuncFormatter and alike.
In matplotlib 3.3.1 I solved this problem via inheritance from ScalarFormatter.
class MyScalarFormatter(ScalarFormatter):
def _formatSciNotation(self, s):
# transform 1e+004 into 1e4, for example
if self._useLocale:
decimal_point = locale.localeconv()['decimal_point']
positive_sign = locale.localeconv()['positive_sign']
else:
decimal_point = '.'
positive_sign = '+'
tup = s.split('e')
try:
significand = tup[0].rstrip('0').rstrip(decimal_point)
sign = tup[1][0].replace(positive_sign, '')
exponent = tup[1][1:].lstrip('0')
if self._useMathText or self._usetex:
if significand == '1' and exponent != '':
# reformat 1x10^y as 10^y
significand = ''
if exponent:
exponent = '10^{%s%s}' % (sign, exponent)
if significand and exponent:
# Here is the only relevant change
return r'%s{\cdot}%s' % (significand, exponent)
else:
return r'%s%s' % (significand, exponent)
else:
s = ('%se%s%s' % (significand, sign, exponent)).rstrip('e')
return s
except IndexError:
return s
and then passing
ax.yaxis.set_major_formatter(MyScalarFormatter())
whenever I like. This worked reliably until new versions of matplotlib came up. Of course I can monkey patch again, but what is a portable and reliable way of achieving the same result in matplotlib>=3.5?