【问题标题】:How to set fixed color ranges with Seaborn heatmap?如何使用 Seaborn 热图设置固定颜色范围?
【发布时间】:2022-06-13 20:12:49
【问题描述】:

我正在尝试使用 Seaborn 包制作热图,我在其中定义自己的颜色范围。但是,我无法让图例以非连续方式显示值。我想要以下颜色指示:

0-0.001:绿色

0.001-0.25:黄色

0.25-0.50:橙色

0.50-0.75:红色

0.75-1.00:深红色

但我明白了:

我怀疑第一个范围会干扰图片,因为它更小。但是,我希望图例“盒子”或区域的大小相同。因此是否有可能有这样或类似的东西:

我目前使用的代码如下。任何提示或建议将不胜感激。谢谢!

my_colors=['#02ab2e','gold','orange','red', 'darkred']


grid_kws = {"height_ratios": (.9, .025), "hspace": .1}
f, (ax, cbar_ax) = plt.subplots(2, gridspec_kw=grid_kws)
ax = sns.heatmap(STEdata.iloc[:,3:13].reindex(ste_order_reg.sort_values().index, axis=0), 
                 yticklabels=2, ax=ax,
                 cmap = my_colors,
                 cbar_ax=cbar_ax, 
                 cbar_kws={"orientation": "horizontal"})
# sns.set(rc = {'figure.figsize':(8, 18)})

colorbar = ax.collections[0].colorbar
colorbar.set_ticks([0, 0, 0.25, 0.5, .75])
colorbar.set_ticklabels(['0',']0-0.25]', ']0.25-0.50]',']0.50-0.75]', ']0.75-1.00]'])

【问题讨论】:

    标签: python matplotlib seaborn legend heatmap


    【解决方案1】:

    要设置不均匀的颜色范围,可以使用BoundaryNorm。颜色条刻度可以位于每个范围的中心。 ListedColormap 从颜色列表创建颜色图。

    import matplotlib.pyplot as plt
    from matplotlib.colors import BoundaryNorm, ListedColormap
    import seaborn as sns
    import numpy as np
    
    my_colors = ['#02ab2e', 'gold', 'orange', 'red', 'darkred']
    my_cmap = ListedColormap(my_colors)
    bounds = [0, 0.0001, 0.25, 0.50, 0.75, 1]
    my_norm = BoundaryNorm(bounds, ncolors=len(my_colors))
    
    grid_kws = {"height_ratios": (.9, .025), "hspace": .1}
    fig, (ax, cbar_ax) = plt.subplots(nrows=2, figsize=(8,18), gridspec_kw=grid_kws)
    sns.heatmap(np.clip(np.random.rand(21, 12) - 0.1, 0, 1),
                yticklabels=2, 
                ax=ax,
                cmap=my_cmap,
                norm=my_norm,
                cbar_ax=cbar_ax,
                cbar_kws={"orientation": "horizontal"})
    
    colorbar = ax.collections[0].colorbar
    colorbar.set_ticks([(b0+b1)/2 for b0, b1 in zip(bounds[:-1], bounds[1:])])
    colorbar.set_ticklabels(['0', ']0-0.25]', ']0.25-0.50]', ']0.50-0.75]', ']0.75-1.00]'])
    
    plt.show()
    

    可以创建自定义图例来代替颜色图。需要相同的BoundaryNorm 在热图中分配正确的颜色。 ax.text()ax.hlines() 可用于放置用于分组的文本和行。 y-axis transform 使用数据的 y 坐标和 x 坐标作为轴的一部分。 clip_on=False 允许在主绘图区域之外绘图。

    import matplotlib.pyplot as plt
    from matplotlib.colors import BoundaryNorm, ListedColormap
    from matplotlib.lines import Line2D
    import seaborn as sns
    import numpy as np
    
    unavail_color = 'lightgray'
    my_colors = ['#02ab2e', 'gold', 'orange', 'red', 'darkred']
    my_cmap = ListedColormap(my_colors)
    bounds = [0, 0.0001, 0.25, 0.50, 0.75, 1]
    my_norm = BoundaryNorm(bounds, ncolors=len(my_colors))
    
    data = np.exp(np.random.rand(21, 12)) - 1
    data[data > 1] = np.nan
    
    fig, ax = plt.subplots(figsize=(8, 18))
    ax.set_facecolor(unavail_color)
    sns.heatmap(data,
                yticklabels=2, ax=ax,
                cmap=my_cmap,
                norm=my_norm,
                cbar=False)
    ax.tick_params(labelsize=16)
    
    group_edges = np.array([0, 5, 6, 13, 14, 21])
    group_labels = ['group A', '', 'group B', '', 'group C']
    ax.hlines(group_edges, np.zeros(len(group_edges)), np.zeros(len(group_edges)) - 0.12,
              color='navy', lw=2, clip_on=False, transform=ax.get_yaxis_transform())
    for label, b0, b1 in zip(group_labels, group_edges[:-1], group_edges[1:]):
        ax.text(-0.12, (b0 + b1) / 2, label, color='navy', fontsize=20, ha='left', va='center',
                rotation=90, transform=ax.get_yaxis_transform())
    
    handles = [Line2D([], [], lw=10, color=color, label=label)
               for color, label in zip(my_colors + [unavail_color],
                                       ['0', ']0-0.25]', ']0.25-0.50]', ']0.50-0.75]', ']0.75-1.00]', 'unavailable'])]
    ax.legend(handles=handles, handlelength=0.5, ncol=len(my_colors) + 1,
              bbox_to_anchor=(0.5, -0.02), loc='upper center', frameon=False)
    
    plt.tight_layout()
    plt.show()
    

    【讨论】:

    • 正是我想要的!非常感谢! :-)
    • 您是否知道是否可以为 y 轴添加组标签?比如在你的第一个图中:0-4: 'group A', 6-12: 'group B', 14-20: 'group C'
    • 你知道我是否也可以根据数据集中的列添加组吗?我有一个带有数字的索引列,然后是一个带有每个数字的组名的列?我找到了这个:stackoverflow.com/questions/19184484/…,但我认为有比这更简单的方法,只需添加额外的名称。
    • 所有这种注释都需要手动调整,就像链接的帖子一样。自动解决方案中会出错的事情太多了。
    【解决方案2】:
    您可以为 cmap 使用任何颜色代码
    例如 cmap='Oranges'

    'Accent'、'Accent_r'、'Blues'、'Blues_r'、'BrBG'、'BrBG_r'、'BuGn'、'BuGn_r'、'BuPu'、'BuPu_r'、'CMRmap'、'CMRmap_r' ,'Dark2','Dark2_r','GnBu','GnBu_r','Greens','Greens_r','Greys','Greys_r','OrRd','OrRd_r','Oranges','Oranges_r',' PRGn','PRGn_r','配对','Paired_r','Pastel1','Pastel1_r','Pastel2','Pastel2_r','PiYG','PiYG_r','PuBu','PuBuGn','PuBuGn_r' ,'PuBu_r','PuOr','PuOr_r','PuRd','PuRd_r','Purples','Purples_r','RdBu','RdBu_r','RdGy','RdGy_r','RdPu',' RdPu_r'、'RdYlBu'、'RdYlBu_r'、'RdYlGn'、'RdYlGn_r'、'Reds'、'Reds_r'、'Set1'、'Set1_r'、'Set2'、'Set2_r'、'Set3'、'Set3_r' ,'光谱','Spectral_r','Wistia','Wistia_r','YlGn','YlGnBu','YlGnBu_r','YlGn_r','YlOrBr','YlOrBr_r','YlOrRd','YlOrRd_r',' afmhot','afmhot_r','autumn','autumn_r','binary','binary_r','bone','bone_r','brg','brg_r','bwr','bwr_r','cividis' ,'cividis_r','cool','cool_r','coolwarm','coolwarm_r','copper','copper_r','crest','crest_r','cubehelix','cubehelix _r'、'flag'、'flag_r'、'flare'、'flare_r'、'gist_earth'、'gist_earth_r'、'gist_gray'、'gist_gray_r'、'gist_heat'、'gist_heat_r'、'gist_ncar'、'gist_ncar_r' ,'gist_rainbow','gist_rainbow_r','gist_stern','gist_stern_r','gist_yarg','gist_yarg_r','gnuplot','gnuplot2','gnuplot2_r','gnuplot_r','gray','gray_r',' hot','hot_r','hsv','hsv_r','icefire','icefire_r','inferno','inferno_r','jet','jet_r','magma','magma_r','mako' ,'mako_r','nipy_spectral','nipy_spectral_r','ocean','ocean_r','pink','pink_r','plasma','plasma_r','prism','prism_r','rainbow',' rainbow_r','rocket','rocket_r','seismic','seismic_r','spring','spring_r','summer','summer_r','tab10','tab10_r','tab20','tab20_r' ,'tab20b','tab20b_r','tab20c','tab20c_r','地形','terrain_r','turbo','turbo_r','twilight','twilight_r','twilight_shifted','twilight_shifted_r',' viridis','viridis_r','vlag','vlag_r','winter','winter_r'

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 1970-01-01
      • 2021-05-08
      • 1970-01-01
      • 2023-03-21
      • 2021-07-06
      • 2021-04-02
      • 2020-10-21
      • 2016-01-21
      相关资源
      最近更新 更多