web-dev-qa-db-ja.com

Python 2.7を使用して、matplotlibプロットの軸に小数位と科学表記を表示できますか?

python 2.7を使用して、pyqtプログラムでmatplotlibを使用していくつかの大きな数値をプロットしています。たとえば、2e + 18と3e + 18の間の値は、いくつかの目盛りで2e + 18だけを読み取るため、2e + 18ではなく2.35e + 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()
17
tempneff

LogFormatterではなくmatplotlib.ticker.FormatStrFormatterを使用する場合、これは非常に簡単です。次のコードは、すべてを'%.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

41
Ffisegydd

科学表記法で適切にフォーマットされたラベルを取得するには、MathText(ラテックス)を使用してラベルに適用するScalarFormatterのフォーマット機能を使用できます。

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()

enter image description here

これは多くの場合に役立ちますが、実際には質問の要件を満たしていません。すべてのラベルで同じ数字を使用するには、よりカスタマイズされたバージョンを使用できます。

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()

enter image description here