Ответ 1
У меня была точно такая же проблема, и эти две строки исправили проблему:
y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
ax.yaxis.set_major_formatter(y_formatter)
У меня есть показатель matplotlib, который я рисую данными, которые всегда упоминаются как наносекунды (1е-9). По оси y, если у меня есть данные, составляющие десятки наносекунд, т.е. 44e-9, значение на оси показывает как 4.4 с a + 1e-8 как смещение. В любом случае, чтобы заставить ось показать 44 с смещением + 1e-9?
То же самое касается моей оси x, где ось показывает + 5.54478e4, где я бы предпочел показать смещение +55447 (целое число, без десятичной величины - значение здесь в днях).
Я пробовал пару таких вещей:
p = axes.plot(x,y)
p.ticklabel_format(style='plain')
для оси x, но это не сработает, хотя я, вероятно, неправильно его использую или неправильно истолковываю что-то из документов, может ли кто-то указать меня в правильном направлении?
Спасибо, Джонатан
Я пробовал делать что-то с formatters, но еще не нашел решения...
myyfmt = ScalarFormatter(useOffset=True)
myyfmt._set_offset(1e9)
axes.get_yaxis().set_major_formatter(myyfmt)
и
myxfmt = ScalarFormatter(useOffset=True)
myxfmt.set_portlimits((-9,5))
axes.get_xaxis().set_major_formatter(myxfmt)
На стороне примечания, я действительно запутался относительно того, где фактически находится объект "номер смещения"... является ли он частью майора/минора?
У меня была точно такая же проблема, и эти две строки исправили проблему:
y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
ax.yaxis.set_major_formatter(y_formatter)
Более простым решением является просто настроить метки меток. Возьмите этот пример:
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()
Обратите внимание, что в случае оси Y множитель умножил значения на 1e9
, а затем упомянул, что константа в y-метке
ИЗМЕНИТЬ
Другим вариантом является подделка множителя экспоненты путем ручного добавления его текста в начало графика:
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
Также вы можете отформатировать смещение по оси X таким же образом:
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)
У вас есть подкласс ScalarFormatter
, чтобы сделать то, что вам нужно... _set_offset
просто добавляет константу, вы хотите установить ScalarFormatter.orderOfMagnitude
. К сожалению, настройка вручную orderOfMagnitude
не будет делать ничего, поскольку она reset, когда экземпляр ScalarFormatter
вызывается для форматирования меток тика оси. Это не должно быть так сложно, но я не могу найти более простой способ сделать именно то, что вы хотите... Вот пример:
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()
Что дает что-то вроде:
В то время как форматирование по умолчанию будет выглядеть так:
Надеюсь, что это поможет!
Изменить: для чего это стоит, я не знаю, где находится метка смещения... Было бы немного проще просто установить ее вручную, но я не мог понять, как это сделать... я почувствуйте, что должен быть более простой путь, чем все это. Он работает, хотя!
Как и в ответе Amro, вы можете использовать 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()
Я думаю, что более элегантным способом является использование форматирования тикера. Вот пример как для xaxis, так и для 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)
Решение Gonzalo начало работать для меня после добавления set_scientific(False)
:
ax=gca()
fmt=matplotlib.ticker.ScalarFormatter(useOffset=False)
fmt.set_scientific(False)
ax.xaxis.set_major_formatter(fmt)
Как было указано в комментариях и в этом ответе, смещение может быть отключено глобально, выполнив следующее:
matplotlib.rcParams['axes.formatter.useoffset'] = False
Для второй части, без ручной перезагрузки всех тиков, это было моим решением:
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)
очевидно, что вы можете установить строку формата так, как хотите.