Mam figurę matplotlib, na której wykreślam dane, które są zawsze określane jako nanosekundy (1e-9). Na osi Y, jeśli mam dane to dziesiątki nanosekund, tj. 44e-9, wartość na osi pokazuje 4,4 z + 1e-8 jako przesunięcie. Czy jest w ogóle wymuszenie na osi pokazania 44 z przesunięciem + 1e-9?
To samo dotyczy mojej osi X, gdzie oś pokazuje + 5.54478e4, gdzie wolałbym, aby pokazywała przesunięcie +55447 (liczba całkowita, bez dziesiętnego - tutaj wartość jest w dniach).
Wypróbowałem kilka rzeczy takich jak ta:
p = axes.plot(x,y)
p.ticklabel_format(style='plain')
dla osi X, ale to nie działa, chociaż prawdopodobnie używam jej nieprawidłowo lub błędnie interpretuję coś z dokumentacji, czy ktoś może wskazać mi właściwy kierunek?
Dzięki, Jonathan
Próbowałem zrobić coś z elementami formatującymi, ale nie znalazłem jeszcze żadnego rozwiązania ...:
myyfmt = ScalarFormatter(useOffset=True)
myyfmt._set_offset(1e9)
axes.get_yaxis().set_major_formatter(myyfmt)
i
myxfmt = ScalarFormatter(useOffset=True)
myxfmt.set_portlimits((-9,5))
axes.get_xaxis().set_major_formatter(myxfmt)
Na marginesie, jestem właściwie zdezorientowany co do tego, gdzie faktycznie znajduje się obiekt „numer przesunięcia”… czy jest to część dużych / pomocniczych taktów?
źródło
set_units
? matplotlib.sourceforge.net/api/… (nie mogę tego wypróbować, ponieważ nie mam tutaj matplotlib.)rcParams
wyłączenie, jeśli domyślnie wyłączone:rcParams["axes.formatter.useoffset"] = False
jak tutaj: stackoverflow.com/questions/24171064/…Odpowiedzi:
Miałem dokładnie ten sam problem, a te linie rozwiązały problem:
from matplotlib.ticker import ScalarFormatter y_formatter = ScalarFormatter(useOffset=False) ax.yaxis.set_major_formatter(y_formatter)
źródło
ax.get_yaxis().get_major_formatter().set_useOffset(False)
from matplotlib.ticker import ScalarFormatter
o kodzie for @Gonzalo do działania lub po prostu użyj rozwiązaniaDużo łatwiejszym rozwiązaniem jest po prostu dostosowanie etykiet kleszczy. Weź ten przykład:
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()
Zwróć uwagę, jak w przypadku osi y pomnożyłem wartości,
1e9
a następnie wspomniałem o tej stałej w etykiecie yEDYTOWAĆ
Inną opcją jest sfałszowanie mnożnika wykładnika przez ręczne dodanie jego tekstu na górze wykresu:
locs,labels = yticks() yticks(locs, map(lambda x: "%.1f" % x, locs*1e9)) text(0.0, 1.01, '1e-9', fontsize=10, transform = gca().transAxes)
EDYCJA2
Możesz również sformatować wartość przesunięcia osi X w ten sam sposób:
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)
źródło
Musisz podklasę,
ScalarFormatter
aby zrobić to, czego potrzebujesz ..._set_offset
po prostu dodaje stałą, którą chcesz ustawićScalarFormatter.orderOfMagnitude
. Niestety ręczne ustawienieorderOfMagnitude
nic nie da, ponieważ jest resetowane, gdyScalarFormatter
instancja jest wywoływana w celu sformatowania etykiet znaczników osi. To nie powinno być takie skomplikowane, ale nie mogę znaleźć prostszego sposobu na zrobienie dokładnie tego, co chcesz ... Oto przykład: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()
Co daje coś takiego:
Natomiast domyślne formatowanie wyglądałoby następująco:
Mam nadzieję, że to trochę pomoże!
Edycja: Nie wiem, gdzie znajduje się etykieta przesunięcia ... Byłoby nieco łatwiej po prostu ustawić ją ręcznie, ale nie mogłem wymyślić, jak to zrobić ... Mam wrażenie że musi być łatwiejszy sposób niż to wszystko. Ale działa!
źródło
Podobnie jak w przypadku odpowiedzi Amro, możesz użyć 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()
źródło
Rozwiązanie Gonzalo zaczęło działać dla mnie po dodaniu
set_scientific(False)
:ax=gca() fmt=matplotlib.ticker.ScalarFormatter(useOffset=False) fmt.set_scientific(False) ax.xaxis.set_major_formatter(fmt)
źródło
Jak wskazano w komentarzach oraz w tej odpowiedzi , offset można wyłączyć globalnie, wykonując następujące czynności:
matplotlib.rcParams['axes.formatter.useoffset'] = False
źródło
Myślę, że bardziej eleganckim sposobem jest użycie programu formatującego. Oto przykład dla osi x i 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)
źródło
W drugiej części, bez ponownego ręcznego resetowania wszystkich ticków, było to moje rozwiązanie:
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)
oczywiście możesz ustawić ciąg formatu na cokolwiek chcesz.
źródło