2017-08-29 191 views
1

我覆蓋補丁在與(簡體)下面的代碼的圖像:matplotlib:匹配傳奇色彩patchCollection顏色

import matplotlib.pyplot as plt 
from scipy.misc import imread 
from matplotlib.collections import PatchCollection 
from matplotlib.patches import Circle, Arrow 
import numpy as np 

def plotFeatures(patches, colours, legends, str_title, colour_scale): 

    fig = plt.figure(); ax = plt.gca() 

    p = PatchCollection(patches, cmap=plt.get_cmap('Spectral_r'), alpha=0.9) 
    p.set_array(np.array(colours)) 
    ax.add_collection(p) 
    p.set_clim(colour_scale) 
    fig.colorbar(p, ax=ax, fraction=0.015) 
    plt.xlabel(str_title) 
    plt.legend(handles=patches, labels=legends, bbox_to_anchor=(0., 1.02, 1., .2), mode='expand', ncol=3, loc="lower left") 
    # ax.set_xticks([]); ax.set_yticks([]) 
    ax.set_xlim([0,100]) 
    ax.set_ylim([0,100]) 


if __name__ == '__main__': 

    my_cmap = plt.get_cmap('Spectral_r') 

    # simplified data structure for example 
    allweights = [ {'name': 'Feature 1', 'mean': 2.1, 'x': 60, 'y':30}, 
        {'name': 'Feature 2', 'mean': 3.0, 'x': 10, 'y':40}, 
        {'name': 'Feature 3', 'mean': 2.5, 'x': 30, 'y':20} ] 

    KPD_patchList = [] 
    KPD_colourList = [] 
    KPD_legendList = [] 

    for w in allweights: 
     KPD_patchList.append(Circle((w['x'], w['y']), w['mean'] + 5)) 
     KPD_colourList.append(w['mean']) 
     KPD_legendList.append('{:s} ({:.2f})'.format(w['name'], w['mean'])) 

    plotFeatures(KPD_patchList, KPD_colourList, KPD_legendList, 'myFeatures', [0, 3]) 

    plt.show() 

導致: enter image description here

然而,在傳說中的補丁不有正確的顏色。

我遇到的問題是我設置了PatchColelction p的顏色,但是plt.legend()不接受PatchColelction的句柄,我必須用不包含顏色數據的補丁來提供它。

我試圖彩色數據直接與facecolor=my_cmap(w['mean']增加了補丁,當我打電話Cricle,如:

for w in allweights: 
     KPD_patchList.append(Circle((w['x'], w['y']), w['mean'] + 5, facecolor=my_cmap(w['mean']))) 
     KPD_colourList.append(w['mean']) 
     KPD_legendList.append('{:s} ({:.2f})'.format(w['name'], w['mean'])) 

但隨後的顏色不equaly比例爲情節:

enter image description here

回答

1

我認爲你的第二次嘗試正處於正確的軌道上,除了你的數據沒有針對色彩地圖正確標準化。 當您嘗試從顏色映射中獲取顏色值時,您需要提供範圍爲[0-1]的值。爲了方便起見,我經常使用matplotlib.cm.ScalarMappablelink to documentation)自動處理這個轉換。

解決你的問題我修改了功能plotFeatures()像這樣:

def plotFeatures(patches, colours, legends, str_title, colour_scale): 

    fig = plt.figure(); ax = plt.gca() 

    p = PatchCollection(patches, cmap=plt.get_cmap('Spectral_r'), alpha=0.9) 
    p.set_array(np.array(colours)) 
    ax.add_collection(p) 
    p.set_clim(colour_scale) 
    fig.colorbar(p, ax=ax, fraction=0.015) 
    plt.xlabel(str_title) 

    # generate legend 
    # create a `ScalarMappable` object with the colormap used, and the right scaling 
    cm = matplotlib.cm.ScalarMappable(cmap=p.get_cmap()) 
    cm.set_clim(colour_scale) 
    # create a list of Patches for the legend 
    l = [Circle((None,None), facecolor=cm.to_rgba(mean_value)) for mean_value in colours] 
    # add legend to plot 
    plt.legend(handles=l, labels=legends, bbox_to_anchor=(0., 1.02, 1., .2), mode='expand', ncol=3, loc="lower left") 


    # ax.set_xticks([]); ax.set_yticks([]) 
    ax.set_xlim([0,100]) 
    ax.set_ylim([0,100]) 

enter image description here

+0

我不得不'進口matplotlib',我改變了變量'l'爲'legend_handles',按[PEP8](https://www.python.org/dev/peps/pep-0008/#names-to-avoid)命名約定。否則完美。 – fuyas