Search code examples
matplotlibnumber-formatting

How do I annotate with power of ten formatting?


I'd like my numbers in annotations be like {x}\cdot10^{y}, not as they are now: {x}E+{y}. Is there a suitable string formatter for this?

The most ideal solution for me would be to use a format string, like '%.2e', but with automatic conversion to the power of ten representation.


Solution

  • You can define your own string formatter for use with LaTeX or Mathtext. In the function sci_notation() defined below you can specify the number of significant decimal digits as well as how many decimal digits to print (default to the number of significant decimal digits). It is also possible to explicitly specify which exponent should be used.

    from math import floor, log10
    
    # Use LaTeX as text renderer to get text in true LaTeX
    # If the two following lines are left out, Mathtext will be used
    import matplotlib as mpl
    mpl.rc('text', usetex=True)
    
    import matplotlib.pyplot as plt
    
    # Define function for string formatting of scientific notation
    def sci_notation(num, decimal_digits=1, precision=None, exponent=None):
        """
        Returns a string representation of the scientific
        notation of the given number formatted for use with
        LaTeX or Mathtext, with specified number of significant
        decimal digits and precision (number of decimal digits
        to show). The exponent to be used can also be specified
        explicitly.
        """
        if exponent is None:
            exponent = int(floor(log10(abs(num))))
        coeff = round(num / float(10**exponent), decimal_digits)
        if precision is None:
            precision = decimal_digits
    
        return r"${0:.{2}f}\cdot10^{{{1:d}}}$".format(coeff, exponent, precision)
    
    scinum = -3.456342e-12
    
    # Annotation with exponent notation using `e` as separator
    plt.annotate(scinum, (0.5,0.5), ha='center', fontsize=20)
    
    # Annotation with scientific notation using `\cdot 10` as separator
    plt.annotate(sci_notation(scinum,1), (0.5,0.4), ha='center', fontsize=20)
    
    # Annotation with scientific notation using `\cdot 10` as separator
    # with 1 significant decimal digit and 2 decimal digits shown as well
    # as a given exponent.
    plt.annotate(sci_notation(scinum,1,2,exponent=-14), (0.5,0.3), ha='center', fontsize=20)
    
    plt.title('Scientific notation', fontsize=14)
    
    plt.show()
    

    enter image description here