2013-06-18 37 views
17

我正在嘗試使用matplotlib繪製我正在處理的紙張的一些數字。我有兩套數據的2D numpy的數組:一個ASCII山體陰影柵格,我可以愉快地繪製,並使用調整:基於Matplotlib中的像素值設置透明度

import matplotlib.pyplot as pp 
import numpy as np 

hillshade = np.genfromtxt('hs.asc', delimiter=' ', skip_header=6)[:,:-1] 

pp.imshow(hillshade, vmin=0, vmax=255) 
pp.gray() 
pp.show() 

其中給出:

Hillshade

並描繪了一個第二ASCII柵格流過風景的河流的特性。這個數據可以用與上面相同的方式繪製,然而陣列中不對應於河流網絡的值被指定爲無數據值-9999。目的是讓沒有數據值設置爲透明,因此河流值覆蓋山體陰影。

這是河流數據,理想情況下這裏表示爲0的每個像素都是完全透明的。

River data

已經做了一些研究這個,看來我也許能到我的數據轉換爲RGBA陣列和設置alpha值,只會使不需要的細胞透明。但是,河流數組中的值是浮點數,並且不能被轉換(因爲原始值是圖的整個點),我相信如果使用RGBA格式,函數只能取無符號整數。

有沒有辦法解決這個限制?我曾希望我可以簡單地創建一個帶有像素值和alpha值的元組,並且像這樣繪製它們,但這看起來不太可能。

我也玩過PIL試圖創建一個沒有數據值透明的河流數據的PNG文件,但是這似乎會自動縮放像素值到0-255,從而失去了我需要的值保存。

我歡迎任何人對此問題有所瞭解。

回答

31

只是掩蓋你的「河流」陣列。

例如

rivers = np.ma.masked_where(rivers == 0, rivers) 

由於以這種方式覆蓋兩個地塊的一個簡單的例子:

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.cm as cm 

# Generate some data... 
gray_data = np.arange(10000).reshape(100, 100) 

masked_data = np.random.random((100,100)) 
masked_data = np.ma.masked_where(masked_data < 0.9, masked_data) 

# Overlay the two images 
fig, ax = plt.subplots() 
ax.imshow(gray_data, cmap=cm.gray) 
ax.imshow(masked_data, cmap=cm.jet, interpolation='none') 
plt.show() 

enter image description here

此外,在一個側面說明,imshow會很樂意接受它的RGBA格式浮動。它只是期望一切在0到1之間的範圍內。

+1

輝煌改變你的門檻!謝謝。我曾希望得到這樣一個優雅的解決方案,但顯然是在樹錯了樹。 – sgrieve

+0

這是限於2個數組還是可以使用3個或更多? – MyCarta

+2

@MyCarta - 它可以處理任意數量的數組,但是你的掩碼錶達式可能會變得複雜。要將布爾表達式與numpy數組結合使用,您需要使用'&'而不是'和','''而不是'或','〜'而不是'not'等。例如:'(a> 5) &(b> 5)'而不是'a> 5和b> 5'。您也不能以完全相同的方式鏈接操作員,例如你需要'(x> 2)&(x <5)'而不是'2> x> 5'。 –

10

另一種使用屏蔽數組的方法可以設置顏色圖如何處理低於最小值clim(無恥地使用Joe Kington's示例):

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.cm as cm 

# Generate some data... 
gray_data = np.arange(10000).reshape(100, 100) 

masked_data = np.random.random((100,100)) 

my_cmap = cm.jet 
my_cmap.set_under('k', alpha=0) 


# Overlay the two images 
fig, ax = plt.subplots() 
ax.imshow(gray_data, cmap=cm.gray) 
im = ax.imshow(masked_data, cmap=my_cmap, 
      interpolation='none', 
      clim=[0.9, 1]) 
plt.show() 

example

有作爲還一個set_over用於夾持關閉頂部和用於在數據設定如何色彩圖手柄「壞」的值的set_bad

這樣做的優點這種方式,你可以通過只調整climim.set_clim([bot, top])