matplotlib:将图例颜色与patchCollection颜色匹配

时间:2017-08-29 11:10:38

标签: python matplotlib

我使用(简化的)以下代码在图像上覆盖补丁:

docker run -v /path/in/host:/var/log/nginx/access.log nginx

结果是: enter image description here

但是图例中的色块没有正确的颜色。

我遇到的问题是我为PatchColelction p设置了颜色,但是plt.legend()不接受句柄的PatchColelction,我必须用不包含颜色数据的补丁来提供它。

当我调用Cricle时,我尝试使用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() 直接向补丁添加颜色数据,如下:

facecolor=my_cmap(w['mean']

然后颜色不像图中那样等级缩放:

enter image description here

1 个答案:

答案 0 :(得分: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