Je trace de grands nombres avec matplotlib dans un programme pyqt en utilisant python 2.7. J'ai un axe y qui va de 1e + 18 à 3e + 18 (généralement). Je voudrais voir chaque coche afficher les valeurs en notation scientifique et avec 2 décimales. Par exemple 2,35e + 18 au lieu de simplement 2e + 18 car les valeurs entre 2e + 18 et 3e + 18 ne lisent toujours que 2e + 18 pour quelques coche. Voici un exemple de ce problème.
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()
C'est vraiment facile à faire si vous utilisez le matplotlib.ticker.FormatStrFormatter
par opposition à LogFormatter
. Le code suivant étiquetera tout au 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()
Afin d'obtenir des étiquettes bien formatées en notation scientifique, on peut utiliser les capacités de formatage d'un ScalarFormatter
qui utilise MathText (Latex) et l'appliquer aux étiquettes.
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()
Bien que cela puisse être utile dans de nombreux cas, il ne répond pas réellement aux exigences de la question. Pour avoir des chiffres égaux sur toutes les étiquettes, une version plus personnalisée peut être utilisée.
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()