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

2024-06-17 11:28:16 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

然而,图例中的补丁没有正确的颜色。在

我的问题是我设置了补丁的颜色,但是plt.图例()不接受手柄的补丁集合,我必须给它提供不包含颜色数据的补丁。在

当我调用Cricle时,我尝试直接用facecolor=my_cmap(w['mean']将颜色数据添加到面片中,如下所示:

^{pr2}$

但是,颜色的比例并不像图中那样均匀:

enter image description here


Tags: namefromimportmatplotlib颜色pltaxmean
1条回答
网友
1楼 · 发布于 2024-06-17 11:28:16

我认为你的第二次尝试是正确的,除了你的数据没有被正确地规范化。 当您试图从colormap获取颜色值时,需要提供一个范围为[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

相关问题 更多 >