cdot for scientific notation in matplotlib

Viewed 86

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?

0 Answers
Related