Show decimal places and scientific notation on the axis of a matplotlib plot

后端 未结 2 863
北海茫月
北海茫月 2020-11-27 14:34

I am plotting some big numbers with matplotlib in a pyqt program using python 2.7. I have a y-axis that ranges from 1e+18 to 3e+18 (usually). I\'d like to see each tick mar

相关标签:
2条回答
  • 2020-11-27 15:04

    This is really easy to do if you use the matplotlib.ticker.FormatStrFormatter as opposed to the LogFormatter. The following code will label everything with the format '%.2e':

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.ticker as mtick
    
    fig = plt.figure()
    
    ax = fig.add_subplot(111)
    
    x = np.linspace(0, 300, 20)
    
    y = np.linspace(0,300, 20)
    y = y*1e16
    
    ax.plot(x,y)
    
    ax.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'))
    
    plt.show()
    

    Example plot

    0 讨论(0)
  • 2020-11-27 15:27

    In order to get nicely formatted labels in scientific notation one may use the formatting capabilities of a ScalarFormatter which uses MathText (Latex) and apply it to the labels.

    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.ticker as mticker
    
    fig, ax = plt.subplots()
    
    x = np.linspace(0, 300, 20)
    y = np.linspace(0,300, 20)
    y = y*1e16
    
    ax.plot(x,y)
    
    f = mticker.ScalarFormatter(useOffset=False, useMathText=True)
    g = lambda x,pos : "${}$".format(f._formatSciNotation('%1.10e' % x))
    plt.gca().yaxis.set_major_formatter(mticker.FuncFormatter(g))
    
    plt.show()
    

    While this may be useful in a lot of cases, it does not actually meet the requirements of the question. To have equal digits on all labels a more customized version can be used.

    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.ticker as mticker
    
    fig, ax = plt.subplots()
    
    x = np.linspace(0, 300, 20)
    y = np.linspace(0,300, 20)
    y = y*1e16
    
    ax.plot(x,y)
    
    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().yaxis.set_major_formatter(MathTextSciFormatter("%1.2e"))
    
    plt.show()
    

    0 讨论(0)
提交回复
热议问题