J'ai un chiffre matplotlib sur lequel je trace des données toujours appelées nanosecondes (1e-9). Sur l’axe des y, si j’ai des données de dizaines de nanosecondes, c’est-à-dire. 44e-9, la valeur sur l’axe indique 4,4 avec un décalage + 1e-8. Est-il possible de forcer l'axe à afficher 44 avec un décalage de + 1e-9?
Il en va de même pour mon axe x où l'axe affiche + 5.54478e4, où je préférerais afficher un décalage de +55447 (nombre entier, pas de décimale - la valeur ici est en jours).
J'ai essayé quelques choses comme ça:
p = axes.plot(x,y)
p.ticklabel_format(style='plain')
pour l'axe des x, mais cela ne fonctionne pas, bien que je l'utilise probablement de manière incorrecte ou que j'interprète mal quelque chose dans la documentation, quelqu'un peut-il m'indiquer dans la bonne direction?
Merci Jonathan
J'ai essayé de faire quelque chose avec les formateurs mais je n'ai pas encore trouvé de solution ...:
myyfmt = ScalarFormatter(useOffset=True)
myyfmt._set_offset(1e9)
axes.get_yaxis().set_major_formatter(myyfmt)
et
myxfmt = ScalarFormatter(useOffset=True)
myxfmt.set_portlimits((-9,5))
axes.get_xaxis().set_major_formatter(myxfmt)
Sur une note de côté, je suis vraiment confus quant à l'endroit où l'objet "numéro de décalage" réside réellement ... fait-il partie des ticks majeurs/mineurs?
J'ai eu exactement le même problème, et ces deux lignes ont résolu le problème:
y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
ax.yaxis.set_major_formatter(y_formatter)
Une solution beaucoup plus simple consiste à personnaliser les libellés de ticks. Prenons cet exemple:
from pylab import *
# Generate some random data...
x = linspace(55478, 55486, 100)
y = random(100) - 0.5
y = cumsum(y)
y -= y.min()
y *= 1e-8
# plot
plot(x,y)
# xticks
locs,labels = xticks()
xticks(locs, map(lambda x: "%g" % x, locs))
# ytikcs
locs,labels = yticks()
yticks(locs, map(lambda x: "%.1f" % x, locs*1e9))
ylabel('microseconds (1E-9)')
show()
Remarquez comment dans le cas de l'axe des y, j'ai multiplié les valeurs par 1e9
puis mentionné cette constante dans l'étiquette y
EDIT
Une autre option consiste à simuler le multiplicateur d'exposant en ajoutant manuellement son texte en haut du graphique:
locs,labels = yticks()
yticks(locs, map(lambda x: "%.1f" % x, locs*1e9))
text(0.0, 1.01, '1e-9', fontsize=10, transform = gca().transAxes)
EDIT2
Vous pouvez également formater la valeur de décalage de l’axe des x de la même manière:
locs,labels = xticks()
xticks(locs, map(lambda x: "%g" % x, locs-min(locs)))
text(0.92, -0.07, "+%g" % min(locs), fontsize=10, transform = gca().transAxes)
Vous devez sous-classer ScalarFormatter
pour faire ce dont vous avez besoin ... _set_offset
ajoute simplement une constante, vous voulez définir ScalarFormatter.orderOfMagnitude
. Malheureusement, définir manuellement orderOfMagnitude
ne fera rien, car il est réinitialisé lorsque l'instance ScalarFormatter
est appelée pour formater les étiquettes de ticks d'axe. Cela ne devrait pas être aussi compliqué, mais je ne trouve pas de moyen plus facile de faire exactement ce que vous voulez ... Voici un exemple:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter, FormatStrFormatter
class FixedOrderFormatter(ScalarFormatter):
"""Formats axis ticks using scientific notation with a constant order of
magnitude"""
def __init__(self, order_of_mag=0, useOffset=True, useMathText=False):
self._order_of_mag = order_of_mag
ScalarFormatter.__init__(self, useOffset=useOffset,
useMathText=useMathText)
def _set_orderOfMagnitude(self, range):
"""Over-riding this to avoid having orderOfMagnitude reset elsewhere"""
self.orderOfMagnitude = self._order_of_mag
# Generate some random data...
x = np.linspace(55478, 55486, 100)
y = np.random.random(100) - 0.5
y = np.cumsum(y)
y -= y.min()
y *= 1e-8
# Plot the data...
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y, 'b-')
# Force the y-axis ticks to use 1e-9 as a base exponent
ax.yaxis.set_major_formatter(FixedOrderFormatter(-9))
# Make the x-axis ticks formatted to 0 decimal places
ax.xaxis.set_major_formatter(FormatStrFormatter('%0.0f'))
plt.show()
Ce qui donne quelque chose comme:
Considérant que, le formatage par défaut ressemblerait à ceci:
J'espère que ça aidera un peu!
Edit: Pour ce que ça vaut, je ne sais pas non plus où se trouve l’étiquette offset ... Ce serait un peu plus facile de la définir manuellement, mais je ne savais pas comment le faire. qu'il doit y avoir un moyen plus facile que tout cela. Cela fonctionne, cependant!
Semblable à la réponse d'Amro, vous pouvez utiliser FuncFormatter
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
# Generate some random data...
x = np.linspace(55478, 55486, 100)
y = np.random.random(100) - 0.5
y = np.cumsum(y)
y -= y.min()
y *= 1e-8
# Plot the data...
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y, 'b-')
# Force the y-axis ticks to use 1e-9 as a base exponent
ax.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: ('%.1f')%(x*1e9)))
ax.set_ylabel('microseconds (1E-9)')
# Make the x-axis ticks formatted to 0 decimal places
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, pos: '%.0f'%x))
plt.show()
La solution de Gonzalo a commencé à fonctionner pour moi après avoir ajouté set_scientific(False)
:
ax=gca()
fmt=matplotlib.ticker.ScalarFormatter(useOffset=False)
fmt.set_scientific(False)
ax.xaxis.set_major_formatter(fmt)
Je pense qu'un moyen plus élégant consiste à utiliser le formateur de ticker. Voici un exemple pour xaxis et yaxis:
from pylab import *
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
majorLocator = MultipleLocator(20)
xFormatter = FormatStrFormatter('%d')
yFormatter = FormatStrFormatter('%.2f')
minorLocator = MultipleLocator(5)
t = arange(0.0, 100.0, 0.1)
s = sin(0.1*pi*t)*exp(-t*0.01)
ax = subplot(111)
plot(t,s)
ax.xaxis.set_major_locator(majorLocator)
ax.xaxis.set_major_formatter(xFormatter)
ax.yaxis.set_major_formatter(yFormatter)
#for the minor ticks, use no labels; default NullFormatter
ax.xaxis.set_minor_locator(minorLocator)
Comme indiqué dans les commentaires et dans cette réponse , le décalage peut être désactivé de manière globale en procédant comme suit:
matplotlib.rcParams['axes.formatter.useoffset'] = False
Pour la deuxième partie, sans réinitialiser manuellement tous les ticks, voici ma solution:
class CustomScalarFormatter(ScalarFormatter):
def format_data(self, value):
if self._useLocale:
s = locale.format_string('%1.2g', (value,))
else:
s = '%1.2g' % value
s = self._formatSciNotation(s)
return self.fix_minus(s)
xmajorformatter = CustomScalarFormatter() # default useOffset=True
axes.get_xaxis().set_major_formatter(xmajorformatter)
évidemment, vous pouvez définir la chaîne de formatage comme vous le souhaitez.