2016-01-05 111 views
2

我認爲這是一個簡單的問題,但我仍然無法想到一個簡單的解決方案。我有一組分子丰度的數據,其值範圍很多。我想用boxplotsbox-and-whiskers plots)來表示這些丰度,並且我希望由於值範圍很廣而以對數標度計算框。 我知道我只能計算數據的log10並將其發送到matplotlib的boxplot,但這並不保留後面的圖表中的對數比例。Matplotlib - Boxplot計算log10值,但以對數形式顯示

所以我的問題基本上是這樣的: 當我計算基於我的價值觀的日誌10箱線圖,我怎麼轉換的情節後來被對數標度,而不是線性與LOG10值顯示? 我可以更改刻度標籤以部分解決此問題,但我不知道如何將對數刻度返回到繪圖。

或者還有另一種更直接的方式來繪製這個。一個不同的包可能已經包含這個選項了?

非常感謝您的幫助。

+0

爲什麼不將log10的計算值轉換回正常值('10 ** y')並將y值設爲對數? – Evert

+0

也許我應該澄清一下,我創建了這樣的情節:'bp \t = \t ax.boxplot(np.log10(abunds))''。該命令計算框值並創建繪圖。我需要改變情節中的東西,而不是價值觀,對吧? – Tobias

+0

你這樣做的方式,你正在繪製不同的東西。我仍然不明白你爲什麼不能做'bp = ax.boxplot(abunds); ax.set_yscale( '登錄')'。這會給你一個對數刻度,因此y-ticks正確地對應你的值。 – Evert

回答

2

我建議不要在原始值上做boxplot,並將y軸設置爲對數,因爲boxplot函數並非設計用於處理跨越數量級的數據,而且您可能會得到太多離羣值(取決於您的數據, 當然)。

相反,我的建議是繪製數據的對數並手動調整y標籤。

這裏是一個非常粗糙的例子:

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.ticker import MultipleLocator, FormatStrFormatter 

np.random.seed(42) 

values = 10 ** np.random.uniform(-3, 3, size=100) 

fig = plt.figure(figsize=(9, 3)) 


ax = plt.subplot(1, 3, 1) 

ax.boxplot(np.log10(values)) 
ax.set_yticks(np.arange(-3, 4)) 
ax.set_yticklabels(10.0**np.arange(-3, 4)) 
ax.set_title('log') 

ax = plt.subplot(1, 3, 2) 

ax.boxplot(values) 
ax.set_yscale('log') 
ax.set_title('raw') 

ax = plt.subplot(1, 3, 3) 

ax.boxplot(values, whis=[5, 95]) 
ax.set_yscale('log') 
ax.set_title('5%') 

plt.show() 

results

右圖顯示的原始值的箱形圖。這會導致很多異常值,因爲最大晶須長度計算爲四分之一範圍(框高度)的倍數(默認值:1.5),其不跨越數量級進行縮放。

可選地,可以指定繪製晶須對於給定的百分值範圍: ax.boxplot(values, whis=[5, 95]) 在這種情況下你得到outlires固定量的(5%)的上方和下方。

+0

謝謝你的好例子。是否還有一種方法可以添加日誌圖的次要滴答,因爲它們在原始圖中? – Tobias

+0

我不知道,對不起。也許可以用'matplotlib來實現。ticker':http://matplotlib.org/examples/pylab_examples/major_minor_demo1.html – kazemakase