2010-09-09 56 views
84

我有一个matplotlib图,我绘制的数据总是被称为纳秒(1e-9)。在y轴上,如果我有数十纳秒的数据,即。 44e-9,轴上的值显示为4.4,其中a + 1e-8作为偏移量。无论如何强迫轴显示44 + 1e-9偏移?matplotlib:将轴的偏移值格式化为整数或具体数字

对于我的x轴同样如此,轴显示+ 5.54478e4,我宁愿它显示偏移+55447(整数,无小数 - 这里的值是天)。

我已经试过几件事情是这样的:

p = axes.plot(x,y) 
p.ticklabel_format(style='plain') 

为x轴,但是,这并不工作,虽然我可能使用它不正确或曲解从文档的东西,可以有人指出我正确的方向?

感谢, 乔纳森

Problem illustration


我试图做与格式化的东西,但还没有找到任何解决方案尚未...:

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) 

在附注中,我实际上对'偏移号码'对象实际存在的位置感到困惑......它是主要/次要蜱的一部分吗?

+1

您是否尝试过'set_units'? http://matplotlib.sourceforge.net/api/axis_api.html#matplotlib.axis.Axis.set_units(我无法尝试它,因为我没有matplotlib这里。) – katrielalex 2010-09-09 14:18:25

+1

我签出了set_units函数,它似乎比必要的方式更复杂(必须编写/添加一个额外的模块 - basic_units?)。必须有一种方法来编辑刻度的格式。 units/set_unit函数看起来更像单位转换线。感谢您的提示,但它让我找到了一些我正在寻找的解决方案! – Jonathan 2010-09-09 18:08:20

+1

请考虑'rcParams'如果默认关闭,请关闭:'rcParams [“axes.formatter.useoffset”] = False' as here:http://stackoverflow.com/questions/24171064/matplotlib-remove-axis-label-抵消默认 – 2016-12-20 10:53:00

回答

25

你必须子类ScalarFormatter做你所需要的... _set_offset只是增加一个常数,你想设置ScalarFormatter.orderOfMagnitude。不幸的是,手动设置orderOfMagnitude将不会执行任何操作,因为在调用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() 

其中产量是这样的: alt text

然而,默认格式将如下所示: alt text

希望能有所帮助!

编辑:对于它的价值,我不知道偏移标签所在的位置......只是手动设置它会稍微容易些,但我无法弄清楚如何去做...我觉得必须有一种比所有这些更简单的方式。它的工作,虽然!

+0

谢谢! ScalarFormatter的子类很好用!但我想我没有清楚地说明我想要的X轴。我想保留x轴的偏移量,但格式化偏移量的值,所以它不会显示为指数。 – Jonathan 2010-09-10 13:30:35

33

更简单的解决方案是简单地自定义刻度标签。借此例如:

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() 

alt text

请注意,在y轴的情况下,我通过1e9相乘的值,则提到,在y标签


EDIT恒定

另一种选择是伪造指数乘数,方法是手动将其文本添加到该图的顶部:

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) 

alt text

+0

刚开始,我就是这么做的。不幸的是,我找不到一个简单的方法来设置/显示轴倍数(除了明确地将其放在y轴标签中,就像您所做的那样)。如果你不介意没有轴倍增标签,这是更简单的方法。无论哪种方式,从我+1。 – 2010-09-09 21:32:05

+1

@Joe Kington:你可以手动添加它作为文本...查看上面的编辑:) – Amro 2010-09-09 21:46:33

+0

太棒了!我将尝试使用x轴标签的方法。我将发布第一个x值,然后从每个x值中删除它,并添加一个“+ minxval”作为标签。我想不出如何格式化x-tick偏移量。我对偏移幅度很好,我只需要它显示为非指数值。 – Jonathan 2010-09-10 13:34:49

11

与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() 
95

我有完全相同的问题,而这两个线固定的问题:再次

y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) 
ax.yaxis.set_major_formatter(y_formatter) 
+1

这是快速和简单的答案。谢谢。 – maxm 2013-07-10 15:37:46

+0

@DanZimm你现在可以upvote ... – 2014-11-10 14:26:09

+0

这不适用于colorbar! – denfromufa 2016-03-16 14:37:12

1

对于第二部分,而无需手动复位所有的蜱虫,这是我的解决方案:

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) 

显然你可以设置格式字符串为任何你想要的。

+0

不幸的是,我还没有调查如何将乘数设置为问题状态的第一部分。 – astrojuanlu 2013-06-29 13:04:57

5

我认为更优雅的方法是使用股票格式化程序。下面是两个X轴和Y轴的例子:

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) 
+1

这不回答问题,它是_how指定科学记数法中使用的offset_和/或_factor。 – hooy 2013-09-07 19:42:46

+0

@nordev即使我的答案没有具体回答这个问题,它仍然给出了一个提示。消息是,你可以选择另一个格式化程序,并得到你想要的,而不是我的例子中的日期。在科学世界里,朱利安日是常态,或者你可以像我的例子那样使用日期。我试图建议的是可以采取不同的方法。有时候可能会问一个问题,因为这个人目前没有更好的主意。不应该抛弃或不尊重替代解决方案。总而言之,我不配得到-1票。 – Bogdan 2014-03-21 00:58:25

5

贡萨洛的解决方案开始为我工作已增加set_scientific(False)后:

ax=gca() 
fmt=matplotlib.ticker.ScalarFormatter(useOffset=False) 
fmt.set_scientific(False) 
ax.xaxis.set_major_formatter(fmt) 
3

正如已指出了意见和in this answer,偏移可能通过执行以下操作关闭:

matplotlib.rcParams['axes.formatter.useoffset'] = False