real - python graficos 2d
matplotlib: valores de desplazamiento del eje de formato a números enteros o número específico (8)
Como se ha señalado en los comentarios y en esta respuesta , el desplazamiento se puede desactivar globalmente, haciendo lo siguiente:
matplotlib.rcParams[''axes.formatter.useoffset''] = False
Tengo una figura matplotlib que estoy trazando datos que siempre se conocen como nanosegundos (1e-9). En el eje y, si tengo datos que son decenas de nanosegundos, es decir. 44e-9, el valor en el eje muestra como 4.4 con un + 1e-8 como un desplazamiento. ¿Hay alguna forma de forzar al eje a mostrar 44 con un desplazamiento de + 1e-9?
Lo mismo vale para mi eje x donde el eje muestra + 5.54478e4, donde prefiero mostrar un desplazamiento de +55447 (número entero, sin decimal - el valor aquí es en días).
He intentado un par de cosas como esta:
p = axes.plot(x,y)
p.ticklabel_format(style=''plain'')
para el eje x, pero esto no funciona, aunque probablemente lo estoy usando incorrectamente o malinterpretando algo de los documentos, ¿alguien puede señalarme en la dirección correcta?
Gracias, Jonathan
Intenté hacer algo con los formateadores, pero todavía no encontré ninguna solución ...
myyfmt = ScalarFormatter(useOffset=True)
myyfmt._set_offset(1e9)
axes.get_yaxis().set_major_formatter(myyfmt)
y
myxfmt = ScalarFormatter(useOffset=True)
myxfmt.set_portlimits((-9,5))
axes.get_xaxis().set_major_formatter(myxfmt)
En una nota lateral, estoy realmente confundido en cuanto a dónde reside realmente el objeto ''número de desplazamiento'' ... ¿es parte de los tics mayores / menores?
Creo que una forma más elegante es usar el formateador ticker. Aquí hay un ejemplo para xaxis y 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)
La solución de Gonzalo comenzó a funcionar para mí después de haber agregado set_scientific(False)
:
ax=gca()
fmt=matplotlib.ticker.ScalarFormatter(useOffset=False)
fmt.set_scientific(False)
ax.xaxis.set_major_formatter(fmt)
Para la segunda parte, sin restablecer manualmente todos los ticks, esta fue mi solución:
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)
obviamente puede establecer la cadena de formato a lo que desee.
Similar a la respuesta de Amro, puede usar 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()
Tenía exactamente el mismo problema, y estas dos líneas resolvieron el problema:
y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
ax.yaxis.set_major_formatter(y_formatter)
Tienes que ScalarFormatter
subclase ScalarFormatter
para hacer lo que necesites ... _set_offset
solo agrega una constante, quieres establecer ScalarFormatter.orderOfMagnitude
. Desafortunadamente, la configuración manual de orderOfMagnitude
no hará nada, ya que se restablece cuando se llama a la instancia de ScalarFormatter
para formatear las etiquetas de los ejes. No debería ser tan complicado, pero no puedo encontrar una manera más fácil de hacer exactamente lo que quieres ... Aquí hay un ejemplo:
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()
Que produce algo así como:
Mientras que, el formato predeterminado se vería así:
¡Espero que esto ayude un poco!
Editar: Por lo que vale, tampoco sé dónde reside la etiqueta de desplazamiento ... Sería un poco más fácil simplemente configurarlo manualmente, pero no pude entender cómo hacerlo ... Tengo la sensación que tiene que haber una manera más fácil que todo esto. ¡Funciona, sin embargo!
Una solución mucho más fácil es simplemente personalizar las etiquetas de tic. Toma este ejemplo:
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()
Observe cómo en el caso del eje y, multipliqué los valores por 1e9
luego mencioné esa constante en la etiqueta y
EDITAR
Otra opción es falsificar el multiplicador del exponente añadiendo manualmente su texto a la parte superior del gráfico:
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
También puede formatear el valor de desplazamiento del eje x de la misma manera:
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)