Python matplotlib:将轴偏移值格式化为整数或特定数字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3677368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
matplotlib: format axis offset-values to whole numbers or specific number
提问by Jonathan
I have a matplotlib figure which I am plotting data that is always referred to as nanoseconds (1e-9). On the y-axis, if I have data that is tens of nanoseconds, ie. 44e-9, the value on the axis shows as 4.4 with a +1e-8 as an offset. Is there anyway to force the axis to show 44 with a +1e-9 offset?
我有一个 matplotlib 图,我正在绘制始终称为纳秒 (1e-9) 的数据。在 y 轴上,如果我有几十纳秒的数据,即。在 44e-9 中,轴上的值显示为 4.4,偏移量为 +1e-8。无论如何强制轴显示 44 和 +1e-9 偏移?
The same goes for my x-axis where the axis is showing +5.54478e4, where I would rather it show an offset of +55447 (whole number, no decimal - the value here is in days).
我的 x 轴也是如此,其中轴显示 +5.54478e4,我宁愿它显示 +55447 的偏移量(整数,没有小数 - 这里的值以天为单位)。
I've tried a couple things like this:
我尝试了一些这样的事情:
p = axes.plot(x,y)
p.ticklabel_format(style='plain')
for the x-axis, but this doesn't work, though I'm probably using it incorrectly or misinterpreting something from the docs, can someone point me in the correct direction?
对于 x 轴,但这不起作用,尽管我可能使用它不正确或误解了文档中的某些内容,有人可以指出我正确的方向吗?
Thanks, Jonathan
谢谢,乔纳森


I tried doing something with formatters but haven't found any solution yet...:
我尝试用格式化程序做一些事情,但还没有找到任何解决方案......:
myyfmt = ScalarFormatter(useOffset=True)
myyfmt._set_offset(1e9)
axes.get_yaxis().set_major_formatter(myyfmt)
and
和
myxfmt = ScalarFormatter(useOffset=True)
myxfmt.set_portlimits((-9,5))
axes.get_xaxis().set_major_formatter(myxfmt)
On a side note, I'm actually confused as to where the 'offset number' object actually resides...is it part of the major/minor ticks?
附带说明一下,我实际上对“偏移量”对象实际所在的位置感到困惑……它是主要/次要刻度的一部分吗?
回答by Joe Kington
You have to subclass ScalarFormatterto do what you need... _set_offsetjust adds a constant, you want to set ScalarFormatter.orderOfMagnitude. Unfortunately, manually setting orderOfMagnitudewon't do anything, as it's reset when the ScalarFormatterinstance is called to format the axis tick labels. It shouldn't be this complicated, but I can't find an easier way to do exactly what you want... Here's an example:
你必须子类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()
Which yields something like:

这产生了类似的东西:

Whereas, the default formatting would look like:

而默认格式如下所示:

Hope that helps a bit!
希望那有所帮助!
Edit: For what it's worth, I don't know where the offset label resides either... It would be slightly easier to just manually set it, but I couldn't figure out how to do so... I get the feeling that there has to be an easier way than all of this. It works, though!
编辑:对于它的价值,我也不知道偏移标签所在的位置......手动设置它会稍微容易一些,但我无法弄清楚如何这样做......我明白了必须有比所有这些更简单的方法。不过,它有效!
回答by Amro
A much easier solution is to simply customize the tick labels. Take this example:
一个更简单的解决方案是简单地自定义刻度标签。拿这个例子:
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()


Notice how in the y-axis case, I multiplied the values by 1e9then mentioned that constant in the y-label
请注意在 y 轴的情况下,我如何将值乘以1e9然后在 y 标签中提到的常量
EDIT
编辑
Another option is to fake the exponent multiplier by manually adding its text to the top of the plot:
另一种选择是通过手动将其文本添加到绘图顶部来伪造指数乘数:
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
编辑2
Also you can format the x-axis offset value in the same manner:
您也可以以相同的方式格式化 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)


回答by idrinkpabst
Similar to Amro's answer, you can use FuncFormatter
类似于 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()
回答by Gonzalo
I had exactly the same problem, and these two lines fixed the problem:
我遇到了完全相同的问题,这两行解决了问题:
y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
ax.yaxis.set_major_formatter(y_formatter)
回答by astrojuanlu
For the second part, without manually resetting all the ticks again, this was my solution:
对于第二部分,无需再次手动重置所有刻度,这是我的解决方案:
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)
obviously you can set the format string to whatever you want.
显然,您可以将格式字符串设置为您想要的任何内容。
回答by Bogdan
I think that a more elegant way is to use the ticker formatter. Here is an example for both xaxis and yaxis:
我认为更优雅的方法是使用股票代码格式化程序。以下是 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)
回答by ha7ilm
Gonzalo's solution started working for me after having added set_scientific(False):
添加了set_scientific(False)以下内容后,Gonzalo 的解决方案开始为我工作:
ax=gca()
fmt=matplotlib.ticker.ScalarFormatter(useOffset=False)
fmt.set_scientific(False)
ax.xaxis.set_major_formatter(fmt)
回答by Evgeni Sergeev
As has been pointed out in the comments and in this answer, the offset may be switched off globally, by doing the following:
正如评论和本答案中所指出的,可以通过执行以下操作来全局关闭偏移量:
matplotlib.rcParams['axes.formatter.useoffset'] = False

