2014-02-20 163 views
27

使用matplotlib當爲軸指定日誌刻度時,標記該軸的默認方法是將數字標記爲10,例如10。 10^6。是否有一種簡單的方法將所有這些標籤更改爲完整的數字表示?例如。 1,10,100等Matplotlib日誌刻度刻度標籤數字格式

請注意,我不知道什麼範圍的權力將是,並且想要支持任意範圍(包括底片)。

回答

39

當然,只需更改格式化程序即可。

例如,如果我們有這樣的情節:

import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 
ax.axis([1, 10000, 1, 100000]) 
ax.loglog() 

plt.show() 

enter image description here

您可以手動設置刻度標記,但隨後的刻度位置和標籤將被固定的,當你縮放/平移/等。因此,最好改變格式:

from matplotlib.ticker import ScalarFormatter 
for axis in [ax.xaxis, ax.yaxis]: 
    axis.set_major_formatter(ScalarFormatter()) 

enter image description here

+0

感謝,正是我想要的。這種簡單的驚訝在這裏沒有其他答案。 –

+1

如果我想將數字更改爲1,5,10,20,該怎麼辦? – aloha

+1

@Joe Kington:我想在50,200之間添加嘀嗒聲,'',我該怎麼做?我試過,'set_xticks [50.0,200.0]'但這似乎不起作用! – ThePredator

20

我發現,使用ScalarFormatter是巨大的,如果你所有的刻度值大於或等於1。但是,如果你有一個勾號在號碼<1處,ScalarFormatter將刻度標籤打印爲0

enter image description here

我用這個lambda函數FuncFormatter>= 1其整數值,和數字<1設置編號,以他們的十進制值,用所需的小數位的最小數目(即0.1, 0.01, 0.001等)。它假定您只設置了base10值的刻度。

import matplotlib.ticker as ticker 
import numpy as np 

ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda y,pos: ('{{:.{:1d}f}}'.format(int(np.maximum(-np.log10(y),0)))).format(y))) 

enter image description here

爲了清楚起見,這裏有一個更詳細,但也更容易理解,這樣寫出來的是lambda表達式:

def myLogFormat(y,pos): 
    # Find the number of decimal places required 
    decimalplaces = int(np.maximum(-np.log10(y),0))  # =0 for numbers >=1 
    # Insert that number into a format string 
    formatstring = '{{:.{:1d}f}}'.format(decimalplaces) 
    # Return the formatted tick label 
    return formatstring.format(y) 

ax.yaxis.set_major_formatter(ticker.FuncFormatter(myLogFormat)) 
+2

這個後續正是我所需要的,謝謝!一個建議:'g'格式說明符不會這樣做嗎?使用'FuncFormatter(lambda y,_:'{:g}'.format(y))'我得到了相同的輸出。 – lenz

+0

是的,我認爲你是對的。在我寫這個答案後,我瞭解了'g'格式化程序:) – tom

2

關於這些問題

什麼如果我想將數字更改爲1,5,10,20?
- ALOHA 7月10日在'15 13:26

我想補充蜱之間,如50200等..,我該怎麼辦 呢?我試過了,set_xticks [50.0,200.0]但這似乎不起作用! - ThePredator 15年3月3日在12:54

但與ax.axis([1,100,1,100]),標量格式給出1.0,10.0,...這不是我所期望的。我想要它給整數... - 中華職棒12月7日在'15 20:22

就可以解決這樣的問題,那些有輕微格式化:

ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter()) 
ax.yaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter("%.8f")) 
ax.set_yticks([0.00000025, 0.00000015, 0.00000035]) 
在我的應用程序

我使用這種格式的方案,我認爲解決了大多數與日誌標量格式相關的問題;同樣可以用於數據> 1.0或x軸格式進行:

plt.ylabel('LOGARITHMIC PRICE SCALE') 
plt.yscale('log') 
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter()) 
ax.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter("%.8f")) 
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter()) 
ax.yaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter("%.8f")) 
##################################################### 
#force 'autoscale' 
##################################################### 
yd = [] #matrix of y values from all lines on plot 
for n in range(len(plt.gca().get_lines())): 
     line = plt.gca().get_lines()[n] 
     yd.append((line.get_ydata()).tolist()) 
yd = [item for sublist in yd for item in sublist] 
ymin, ymax = np.min(yd), np.max(yd) 
ax.set_ylim([0.9*ymin, 1.1*ymax]) 
##################################################### 
z = [] 
for i in [0.0000001, 0.00000015, 0.00000025, 0.00000035, 
      0.000001, 0.0000015, 0.0000025, 0.0000035, 
      0.00001, 0.000015, 0.000025, 0.000035, 
      0.0001, 0.00015, 0.00025, 0.00035, 
      0.001, 0.0015, 0.0025, 0.0035, 
      0.01, 0.015, 0.025, 0.035, 
      0.1, 0.15, 0.25, 0.35]: 

    if ymin<i<ymax: 
     z.append(i) 
     ax.set_yticks(z)     

有關 「力的自動縮放」 的評論見:Python matplotlib logarithmic autoscale

其產生:

enter image description here

然後創建一個通用機器:

# user controls 
##################################################### 
sub_ticks = [10,11,12,14,16,18,22,25,35,45] # fill these midpoints 
sub_range = [-8,8] # from 100000000 to 0.000000001 
format = "%.8f" # standard float string formatting 

# set scalar and string format floats 
##################################################### 
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter()) 
ax.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter(format)) 
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter()) 
ax.yaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter(format)) 

#force 'autoscale' 
##################################################### 
yd = [] #matrix of y values from all lines on plot 
for n in range(len(plt.gca().get_lines())): 
     line = plt.gca().get_lines()[n] 
     yd.append((line.get_ydata()).tolist()) 
yd = [item for sublist in yd for item in sublist] 
ymin, ymax = np.min(yd), np.max(yd) 
ax.set_ylim([0.9*ymin, 1.1*ymax]) 

# add sub minor ticks 
##################################################### 
set_sub_formatter=[] 
for i in sub_ticks: 
    for j in range(sub_range[0],sub_range[1]): 
     set_sub_formatter.append(i*10**j) 
k = [] 
for l in set_sub_formatter: 
    if ymin<l<ymax: 
     k.append(l) 
ax.set_yticks(k) 
##################################################### 

產量:

enter image description here