2015-03-02 38 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