2017-01-11 39 views
1

我有一個二維三角形網格與n個頂點存儲在一個變量tri(matplotlib.tri.Triangulation對象);我可以很容易地用matplotlib的tripcolor函數繪製網格,一切正常。但是,對於每個頂點(vcolors),我也有(r,g,b)三元組,並且這些值不會沿着一個維度下降,因此不能輕易轉換爲色彩映射(例如,想象一下,如果覆蓋一個公園的大照片上的三角形網格,然後爲每個頂點分配其下面的像素的顏色)。tripcolor使用RGB值爲每個頂點

我想我能夠做這樣的事情:

matplotlib.pyplot.tripcolor(tri, vcolors) 

ValueError: Collections can only map rank 1 arrays

是否有一個vcolors樣(N×3)矩陣轉換成可用tripcolor東西方便的方法?是否有替代tripcolor接受頂點顏色?

有一件事我已經試過是使自己的顏色表:

z = numpy.asarray(range(len(vcolors)), dtype=np.float)/(len(vcolors) - 1) 
cmap = matplotlib.colors.Colormap(vcolors, N=len(vcolors)) 
matplotlib.pyplot.tripcolor(tri, z, cmap=cmap) 
matplotlib.pyplot.show() 

然而,這什麼也沒做---沒有數字似乎並不會引發錯誤;該函數返回一個圖形句柄,但沒有任何東西會呈現(我正在使用IPython筆記本)。請注意,如果我打電話給以下內容,則情節顯示得很好:

tripcolor(tri, np.zeros(len(vcolors))) 
matplotlib.pyplot.show() 

我正在使用Python 2.7。

+0

我刪除了我的答案,因爲它顯然沒有幫助。爲了防止進一步的混亂:如果你想gouraud陰影,在問題中提到它。由於tripcolor不允許Gouraud陰影與「facecolors」參數一起使用,所以除了使用色彩映射外,沒有解決方法。如果不同顏色的數量是有限的,則可能的解決方案可能是創建自定義顏色圖,例如,如果您只有255個不同的顏色值,則可以創建這255個值的顏色表。 – ImportanceOfBeingErnest

+0

Gouraud着色是一個加號,但我不需要它。有或沒有古洛德陰影,你的斷言,「facecolors」的論點可以解決這個問題似乎是錯誤的:它仍然需要一個1D的z向量,根據顏色映射解釋。它不能幫助我從每個頂點的RGB三元組轉換爲可用的。我的問題要求可以處理這種情況的「tripcolor」的替代方法,所以我不同意沒有解決方案是可能的。它還明確指出,自定義色彩映射解決方案失敗,所以如果你有一個解決方法,我很樂意聽到它(顏色數量是'len(vcolors)')。 – user16054

回答

1

matplotlib亂翻後的tripcolorColormap代碼,我想出了以下解決方案,這似乎只工作,只要一使用‘高氏’陰影(否則,它演繹着一個非常差的工作面部顏色;見下文)。

訣竅是創建一個,01(含)之間的給定的n均勻間隔的號碼,當顏色表再現的顏色的原始數組:

def colors_to_cmap(colors): 
    ''' 
    colors_to_cmap(nx3_or_nx4_rgba_array) yields a matplotlib colormap object that, when 
    that will reproduce the colors in the given array when passed a list of n evenly 
    spaced numbers between 0 and 1 (inclusive), where n is the length of the argument. 

    Example: 
     cmap = colors_to_cmap(colors) 
     zs = np.asarray(range(len(colors)), dtype=np.float)/(len(colors)-1) 
     # cmap(zs) should reproduce colors; cmap[zs[i]] == colors[i] 
    ''' 
    colors = np.asarray(colors) 
    if colors.shape[1] == 3: 
     colors = np.hstack((colors, np.ones((len(colors),1)))) 
    steps = (0.5 + np.asarray(range(len(colors)-1), dtype=np.float))/(len(colors) - 1) 
    return matplotlib.colors.LinearSegmentedColormap(
     'auto_cmap', 
     {clrname: ([(0, col[0], col[0])] + 
        [(step, c0, c1) for (step,c0,c1) in zip(steps, col[:-1], col[1:])] + 
        [(1, col[-1], col[-1])]) 
     for (clridx,clrname) in enumerate(['red', 'green', 'blue', 'alpha']) 
     for col in [colors[:,clridx]]}, 
     N=len(colors)) 

再次注意,'gouraud'陰影爲此需要上班。爲了演示失敗的原因,以下代碼塊顯示了我的特定用例。 (我正在繪製一部分具有部分透明數據覆蓋的扁平皮質片)。在此代碼中,有40,886個頂點(在the_map.coordinates中)和81,126個三角形(在the_map.indexed_faces中); colors陣列的形狀爲(40886, 3)

下面的代碼工作正常「高氏」陰影:根據平均的頂點

tri = matplotlib.tri.Triangulation(the_map.coordinates[0], 
            the_map.coordinates[1], 
            triangles=the_map.indexed_faces.T) 
cmap = rgbs_to_cmap(colors) 
zs = np.asarray(range(the_map.vertex_count), dtype=np.float)/(the_map.vertex_count - 1) 
plt.figure(figsize=(16,16)) 
plt.tripcolor(tri, zs, cmap=cmap, shading='gouraud') 

Plot using Gouraud shading

但是,如果沒有「高氏」的陰影,也許是被分配臉部顏色(有沒有驗證了這一點),這顯然是錯誤的:

plt.figure(figsize=(16,16)) 
plt.tripcolor(tri, zs, cmap=cmap) 

enter image description here

0

一個顏色貼圖的更簡單的方法是通過from_list

z = numpy.arange(n) 
cmap = matplotlib.colors.LinearSegmentedColormap.from_list(
    'mymap', rgb, N=len(rgb) 
    )