Python 在 matplotlib 图的轴上显示小数位和科学记数法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/25750170/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Show decimal places and scientific notation on the axis of a matplotlib plot
提问by tempneff
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 mark show values in scientific notation and with 2 decimal places. For example 2.35e+18 instead of just 2e+18 because values between 2e+18 and 3e+18 still read just 2e+18 for a few tickmarks. Here is an example of that problem.
我正在使用 python 2.7 在 pyqt 程序中用 matplotlib 绘制一些大数字。我有一个 y 轴,范围从 1e+18 到 3e+18(通常)。我希望看到每个刻度线都以科学记数法显示值并保留 2 位小数。例如,2.35e+18 而不是 2e+18,因为 2e+18 和 3e+18 之间的值对于一些刻度线仍然只读取 2e+18。这是该问题的一个示例。
import numpy as np
import matplotlib.pyplot as plt
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.get_xaxis().set_major_formatter(plt.LogFormatter(10,  labelOnlyBase=False))
ax.get_yaxis().set_major_formatter(plt.LogFormatter(10,  labelOnlyBase=False))
plt.show()
采纳答案by Ffisegydd
This is really easy to do if you use the matplotlib.ticker.FormatStrFormatteras opposed to the LogFormatter. The following code will label everything with the format '%.2e':
如果您使用 而matplotlib.ticker.FormatStrFormatter不是LogFormatter. 以下代码将使用格式标记所有内容'%.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()


回答by ImportanceOfBeingErnest
In order to get nicely formatted labels in scientific notation one may use the formatting capabilities of a ScalarFormatterwhich uses MathText (Latex) and apply it to the labels. 
为了以科学记数法获得格式良好的标签,可以使用ScalarFormatter使用 MathText (Latex)的 a 的格式化功能并将其应用于标签。
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()

