2013-06-18 6 views
17

Próbuję użyć matplotlib, aby narysować kilka liczb dla papieru, nad którym pracuję. Mam dwa zestawy danych w tablicach 2D NumPy: ASCII hillshade raster które mogę szczęśliwie działki i dostosować przy użyciu:Ustawianie przezroczystości na podstawie wartości pikseli w 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() 

Co daje:

Hillshade

I drugi raster ASCII, który wyznacza właściwości rzeki płynącej przez krajobraz. Dane mogą być nanoszone w taki sam sposób, jak powyżej, jednak wartości w tablicy, które nie odpowiadają sieci rzeki, są przypisywane zerowej wartości danych -9999. Celem jest, aby wartości danych nie były ustawione jako przejrzyste, tak aby wartości rzeki pokrywały górny stok.

To jest dane o rzece, najlepiej każdy piksel reprezentowany tutaj jako 0 będzie całkowicie przezroczysty.

River data

Uczyniwszy rozeznanie w tej sprawie wydaje się, może będę w stanie przekształcić moje dane do tablicy RGBA i ustawić wartości alfa względem tylko sprawiają, że niechciane komórki przejrzyste. Jednak wartości w tablicy river są wartościami zmiennoprzecinkowymi i nie można ich przekształcić (ponieważ oryginalne wartości stanowią cały punkt na figurze) i uważam, że funkcja imshow może przyjmować tylko liczby całkowite bez znaku, jeśli używany jest format RGBA.

Czy istnieje jakieś obejście tego ograniczenia? Miałem nadzieję, że po prostu utworzę krotkę z wartością piksela i wartością alfa i tak je wykreślę, ale to nie wydaje się możliwe.

Mam również grę z PIL, aby spróbować utworzyć plik PNG z danymi rzeki bez wartości przezroczystości danych, jednak wydaje się, że automatycznie skaluje wartości pikseli do 0-255, tracąc w ten sposób wartości, których potrzebuję zachować.

Chciałbym powitać każdy wgląd, który ktoś ma na temat tego problemu.

Odpowiedz

31

Po prostu ukryj swoją "rzekę".

np.

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

Jako szybki przykład nakładając dwie działki w ten sposób:

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

Ponadto, na marginesie, imshow chętnie akceptują pływaków swojej formacie RGBA. Po prostu oczekuje, że wszystko będzie w zakresie od 0 do 1.

+1

Brilliant! Dziękuję Ci. Miałem nadzieję na takie eleganckie rozwiązanie, ale najwyraźniej szczekałem złe drzewo. – sgrieve

+0

Czy jest to ograniczone do 2 tablic lub czy działałoby z 3 lub więcej? – MyCarta

+2

@MyCarta - Będzie działać z tylu tablic, ile chcesz, ale twoje wyrazy maskujące mogą stać się skomplikowane. Aby łączyć wyrażenia logiczne z numpy tablicami, należy użyć 'i' zamiast 'i', '|' zamiast 'lub', '~' zamiast 'not', itp. Na przykład:' (a> 5) & (b> 5) 'zamiast' a> 5 i b> 5'. Nie będziesz też mógł łączyć operatorów w podobny sposób, np. potrzebujesz '(x> 2) i (x <5)' zamiast '2> x> 5'. –

10

Alternatywnym sposobem wykonania tej czynności bez użycia zamaskowanych tablic jest ustawienie sposobu, w jaki mapa kolorów radzi sobie z wartościami przycinania poniżej minimum clim (bezwstydnie za pomocą Joe Kington's przykład):

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

tam również set_over do obcinania wierzchołka i set_bad ustawiania how „zły” wartości Mapa koloru uchwyty w danych.

Zaletą robi to w ten sposób to można zmienić tylko przez próg dostosowania clim z im.set_clim([bot, top])