pythonmatplotlibfontsaxis-labelsscientific-notation

Scientific notation on the axis (literature style) - how to change default font?


I need a literature-style scientific notation on both axes in matplotlib with specific font.

In my search I found this question with an answer for literature-style scientific notation from ImportanceOfBeingErnest: Show decimal places and scientific notation on the axis

There are no details about changing font though.

My code:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker

fig,ax=plt.subplots(1,1,figsize=[7,7])

x=np.linspace(0,0.1,10**3)
y=x**2

ax.plot(x,y)

# code from ImportanceOfBeingErnest
class MathTextSciFormatter(mticker.Formatter):
    def __init__(self, fmt="%1.2e"):
        self.fmt = fmt
    def __call__(self, x, pos=None):
        s = self.fmt % x
        decimal_point = '.'
        positive_sign = '+'
        tup = s.split('e')
        significand = tup[0].rstrip(decimal_point)
        sign = tup[1][0].replace(positive_sign, '')
        exponent = tup[1][1:].lstrip('0')
        if exponent:
            exponent = '10^{%s%s}' % (sign, exponent)
        if significand and exponent:
            s =  r'%s{\times}%s' % (significand, exponent)
        else:
            s =  r'%s%s' % (significand, exponent)
        return "${}$".format(s)

# Format with 2 decimal places
plt.gca().xaxis.set_major_formatter(MathTextSciFormatter("%1.2e"))
plt.gca().yaxis.set_major_formatter(MathTextSciFormatter("%1.2e"))
# end of code from ImportanceOfBeingErnest

plt.xticks(rotation=45,font="Arial",fontsize=20)

for tick in ax.get_yticklabels():
    tick.set_fontname("Arial")

Result: Graph from code

The literature-style scientific notation is implemented but none of the two methods of changing font work. Interestingly though, the fontsize can be changed.

Could anyone provide a solution for changing font with this notation?

matplotlib 3.5.3


Solution

  • You are using matplotlib's internal mathtext renderer with r'$...$' syntax, but you are changing the font only for regular text. You could use

    import matplotlib as mpl
    
    mpl.rcParams["mathtext.fontset"] = 'custom'
    mpl.rcParams['mathtext.rm']='Arial'
    

    to change math fonts everywhere, which is probably what you are after. I would prefer Arimo, which is a free font that is metrically compatible with Arial. See the documentation for details on customising individual fonts for bold, calligraphic etc.

    Alternatively you could use an external TeX renderer with

    mpl.rc('text', usetex=True)
    

    but you will need to supply the necessary LaTeX preamble to use Arial font.