matplotlib:将轴偏移值格式化为整数或特定数字


92

我有一个matplotlib图,该图正在绘制始终被称为纳秒(1e-9)的数据。在y轴上,如果我有数十纳秒的数据,即 在44e-9中,轴上的值显示为4.4,其中+ 1e-8为偏移量。无论如何,有强制轴以+ 1e-9偏移显示44吗?

我的x轴也是如此,该轴显示+ 5.54478e4,我希望它显示+55447的偏移量(整数,无小数-该值以天为单位)。

我已经尝试了一些类似的事情:

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

对于x轴,但这不起作用,尽管我可能使用不正确或对文档中的内容有误解,有人可以指出我正确的方向吗?

谢谢乔纳森

问题图


我尝试使用格式化程序进行操作,但尚未找到任何解决方案...:

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吗?matplotlib.sourceforge.net/api/…(我无法尝试,因为这里没有matplotlib。)
Katriel 2010年

1
我检查了set_units函数,它看起来比必要的方法复杂得多(必须编写/添加一个附加模块?? basic_units?)。必须有一种方法来编辑刻度线的格式。单位/ set_unit函数似乎更像是单位转换。不过,感谢您提供的技巧,它使我获得了目前正在寻找的其他解决方案!
乔纳森

1
请考虑rcParams到如果把默认关闭:rcParams["axes.formatter.useoffset"] = False如下:stackoverflow.com/questions/24171064/...
鲁杰罗Turra

Answers:


100

我遇到了完全相同的问题,这些行解决了这个问题:

from matplotlib.ticker import ScalarFormatter

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

1
这是快速简便的答案。谢谢。
maxm

6
一线将是:ax.get_yaxis().get_major_formatter().set_useOffset(False)
Dataman

3
对于像我这样的菜鸟来说,请不要忘记from matplotlib.ticker import ScalarFormatter@Gonzalo的代码可以正常工作,或者只使用上面的
@Dataman

36

一个简单得多的解决方案是简单地自定义刻度标签。举个例子:

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)

编辑2

同样,您也可以通过以下方式设置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)

替代文字


刚开始我就是这么做的。不幸的是,我找不到设置/显示轴倍增器的简单方法(除了像您一样将其显式地放置在y轴标签中)。如果您不介意没有轴倍增器标签,这是更简单的方法。无论哪种方式,我都会+1。
乔·肯顿2010年

1
@Joe Kington:您可以将其手动添加为文本...请参见上面的编辑:)
Amro 2010年

大!我将尝试使用带有x轴标签的方法。我先讲第一个x值,然后将其从每个x值中删除,然后添加“ + minxval”作为标签。我不知道如何格式化X-tick偏移量。我对偏移量的大小表示满意,我只需要将其显示为非指数值即可。
乔纳森

哇。在展示如何真正控制matplotlib并将其调整为您的需求以及对场景进行一些调整方面的出色工作。
physicsmichael 2011年

如何更改图中1e-9的字体大小?
报价不能拒绝

30

您必须子类化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()

产生如下内容: 替代文字

而默认格式如下所示: 替代文字

希望那有所帮助!

编辑:对于它的价值,我也不知道偏移标签在哪里...手动设置它会稍微容易些,但是我不知道该怎么做...我有种感觉必须有比这更简单的方法。它有效,但是!


谢谢!子类化ScalarFormatter的效果很好!但是我想我没有明确说明我想要的X轴。我想保留x轴的偏移量,但是格式化偏移量的值,以便不将其显示为指数。
乔纳森(Jonathan)2010年

这是唯一对我有用的方法!谢谢:)
海洋科学家

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

5

添加set_scientific(False)以下内容后,Gonzalo的解决方案开始为我工作:

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


4

我认为一种更优雅的方法是使用股票代码格式器。这是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)

1
这没有回答问题,即如何指定科学计数法中使用的偏移量和/或因子
2013年

@nordev即使我的答案没有明确回答问题,它仍然会提示您。消息是您可以选择其他格式化程序,而不是从我的示例中获取日期,然后获取所需的格式。在科学界,儒略日是常态,或者您可以像我的示例中那样使用日期。我试图建议的是可以采用不同的方法。有时可能会问一个问题,因为这个人目前还没有一个更好的主意。替代溶液不应丢弃或不尊重对待。总而言之,我不值得-1票。
Bogdan 2014年

2

对于第二部分,这是我的解决方案,而无需再次手动重置所有刻度线:

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)

显然,您可以将格式字符串设置为所需的任何格式。


不幸的是,我还没有研究如何将乘数设置为问题状态的第一部分。
astrojuanlu 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.