2015-03-02 41 views
0

我基本上想要的是不用绘图和有偏移量10^8 10^5或1e8 1e5等等,使它们以诸如10^3 10^6 1e3 1e6等stadard单位表示。Matplotlib:格式偏移到标准单位

这可能吗?如果是的话如何?

在此先感谢

+1

这是你想控制的偏移量:http://stackoverflow.com/q/3677368/190597? – unutbu 2015-03-02 14:29:58

回答

1
plt.gca().get_xaxis().get_major_formatter().set_useOffset(False) 

你的意思呢? (y轴也一样)。这是this问题的一个可能的重复,其中第二个答案给出比我更规范的描述。 Upvote他,如果这就是你要找的。

编辑

我这个上下车玩耍了整个下午,似乎设置ax.yaxis.set_scientific(True)自动胜过任何ax.yaxis.setOffset = False。无论你用哪种方式做。我无法解决这个问题,然后我加重了。

下面是一个解决方法,Py3.4,mpl 1-3-1 win7测试。

import matplotlib as mpl 
import matplotlib.pyplot as plt 
import numpy as np 
from decimal import Decimal 

x_large = np.arange(10, 20000, 100) 
y_large = np.arange(10, 20000, 100) 

x_small = np.arange(-1, 1, 0.000001) 
y_small = np.arange(-1, 1, 0.000001) 

metric = [0,1,2,3,6,9, 12, 16] 

def format_large(x): 
    x = float(x) 
    sx = str(x) 
    sx = sx.split(".")[0] 
    if len(sx)-1 in metric: 
     return "%se%s" % (sx[0], len(sx)-1) 
    add = - max(exp-len(sx)-1 for exp in metric if exp<len(sx)-1) 
    return "%se%s" % (sx[0:add], len(sx)-add) 

#love thy DRY principle 
def check_metric_small(num, exp): 
    if exp in metric: 
      return "%se-%s" % (num[0], exp) 
    add = min(mexp-exp for mexp in metric if mexp>exp) 
    num = num.ljust(add+1, "0") 
    return "%se-%s" % (num[0:add+1], exp+add) 

def format_small(x): 
    sx = str(x) 
    #string representation of numbers after e-4 is 
    #done in scientific manner 1e-5, 1e-6 ... 
    if sx.find("e") != -1: 
     num, exp = sx.split("e") 
     exp = -int(exp) 
     return check_metric_small(num, exp) 
    #numbers up to e-4 are represented in string form 
    #as is, therefore 0.1, 0.01 
    s = sx.split(".")[-1] 
    num = s.strip("0") 
    exp = len(s)-len(num) 
    return check_metric_small(num, exp+1) 


def formatter(x, p): 
    if x<0: #make sure we don't send a negative number 
     res = "-" #rather just tack on the minus sign 
     x = -x 
    else: res = ""   
    if abs(x)<1 and x!=0.0: 
      return res+format_small(x) 
    return res+format_large(x) 

fig, ax = plt.subplots() 
y_formatter = mpl.ticker.FuncFormatter(formatter) 
ax.yaxis.set_major_formatter(y_formatter) 
ax.plot(x_large,y_large) 

plt.show() 

凡重要的功能包含了format_largeformat_small内。他们会将数字四舍五入为由metric列表定义的下一个最接近的较小指数。他们自己无法处理负数,因此请使用formatter函数。

大变焦和未变焦之间的变化似乎没有留下任何奇怪的效果,也没有超过零。贝娄是这些功能的要点是:

for i in [0, 10, 50, ......]: 
    print(format_large(i), float(format_large(i)) == i) 

0e0 True   5e6 True 
1e1 True   5e6 True 
5e1 True   50e6 True 
5e2 True   500e6 True 
5e3 True   50e9 True 
50e3 True   500e9 True 
500e3 True   5e12 True 

for i in [0.05, 0.005, ......]: 
    print(format_small(i), float(format_small(i)) == i) 

5e-2 True   50e-9 True 
5e-3 True   5e-9 True 
500e-6 True  500e-12 True 
50e-6 True  50e-12 True 
5e-6 True   50e-12 True 
500e-9 True  5000e-16 True 

不过要小心,因为我圆数字,你只能用圆润的数字测试。

对于大数字会发生什么,是我将它们的字符串表示形式,即"500.0"。数字的长度减去一个数字后给出数字的个数。如果它是一个度量顺序,我将返回最简单的字符串,其中只包含数字的前导数字及其指数。

如果数字的顺序不是度量标准,我找到第一个较低的度量指数:max(exp-len(sx) for exp in metric if exp<len(sx))(这意味着,找到指数度量系统和我当前的数字顺序之间的最大差异,低于当前的订单数量)。这保证了所有的差异都是负的,最大的数字总是指向最接近的度量指数。返回字符串,其中“主”号具有多于一位的数字,多少由最接近的度量指数与当前号码顺序之间的差值决定。

小数字变得非常复杂,因为有两种情况需要考虑。当一个数字大于0.0004时,其表示不会被改变。然而,对于小于这个数字的人来说,他们的表现将会变成科学。

我将字母“e”的科学表示法拆分为实际数字,即1234和指数。如果指数属于公制系统,则返回字符串。否则,请给我下一个较小的度量标准索引,并填充数字直到它适合:mexp-exp for mexp in metric if mexp>exp(这意味着:对于大于当前数字顺序的所有指数,并记住我将当前顺序更改为正数,因此较大的度量指数与较小实际数量,找到当前和度量指数的最小差异)。在返回字符串之前,我使用ljust填充数字的右侧,因此我不会冒险提高索引超出范围的错误。

对于不具有科学代表性的小数字,即0.000432,我将它们拆分为.,去掉前导零以得到数字432。从整个拆分号码000432的长度中减去的长度决定了我有多少个零。从那里我重复查找下一个最接近的度量指数的过程,或者立即返回一个字符串。

函数没有小数点数选项,但添加它应该是微不足道的。在返回结果并将返回语句修改为"%s%se%s" % (sx[0:add], sx[add:ndecimals], len(sx)-add)之前的if语句应该处理该问题。

我想说这很有趣。但事实并非如此:D直到我放弃为止,它才通过手册煞有介事。但我说过,我会尽快回复你。

+0

nope。我想保留偏移量。但使用标准单位。 (Kilo兆等等10^3 10^6等) – 2015-03-02 14:35:14

+0

以及它是没有重复。我不是试图关闭偏移量,而是强制使用标准单位。而不是使用随机功率或指数,如1e5或10^5我想格式化的规模和抵消使用10^6或1e6这是兆的标准单位。 https://en.wikipedia.org/wiki/International_System_of_Units#Prefixes – 2015-03-02 14:46:20

+0

@OrestisIoannou是的,我明白了。我不能拿回国旗,但我向你保证它不会被接受。有'set_scientific'选项可以在'ScalarFormater'中使用,但是我无法使用它。我会在一两分钟内编辑 – ljetibo 2015-03-02 14:46:55