【问题标题】:Seaborn custom range heatmapSeaborn 自定义范围热图
【发布时间】:2021-05-08 17:19:42
【问题描述】:

我需要根据这些要求构建自定义的 seaborn 类热图:

import pandas as pd
df = pd.DataFrame({"A": [0.3, 0.8, 1.3], 
                   "B": [4, 9, 15], 
                   "C": [650, 780, 900]})

df_info = pd.DataFrame({"id": ["min", "max"],
                   "A": [0.5, 0.9], 
                   "B": [6, 10], 
                   "C": [850, 880]})
df_info = df_info.set_index('id')

df


    A      B    C
0   0.3    4    650
1   0.8    9    780
2   1.3    15   900

df_info

id      A      B    C
            
min     0.5    6    850
max     0.9    10   880

df 中的每个值都应该在df_info 中定义的范围内。
例如,A 列的值如果在 0.5 和 0.9 之间,则被认为是正常的。超出范围的值应使用自定义热图进行着色。

特别是:

  • 在为每列定义的范围内的值不应在白色背景单元格上用纯黑色文本着色。
  • 该列低于min 的值应着色,例如蓝色。从 min 开始,它们的值越低,蓝色的阴影越深。
  • 该列的高于max 的值应着色,例如红色。从最大值开始,它们的值越高,红色越深。

问:我不知道如何使用标准热图来解决此问题,我什至不确定是否可以使用热图来完成此操作。有什么建议吗?

【问题讨论】:

    标签: python pandas seaborn heatmap


    【解决方案1】:

    据我所知,热图只能有一个数值范围。我建议对 df 数据框中的数据进行规范化,以便每一列中的值如下:

    • 介于01 之间,如果值介于df_infomin max 之间
    • 低于0 如果值低于df_infomin
    • 高于1,如果该值高于df_infomax

    要规范化您的数据框,请使用:

    for col in df:
        df[col] = (df[col] - df_info[col]['min']) / (df_info[col]['max'] - df_info[col]['min'])
    

    最后,创建颜色编码的热图使用:

    import seaborn as sns
    from matplotlib.colors import LinearSegmentedColormap
    
    vmin = df.min().min()
    vmax = df.max().max()
    
    colors = [[0, 'darkblue'],
              [- vmin / (vmax - vmin), 'white'],
              [(1 - vmin)/ (vmax - vmin), 'white'],
              [1, 'darkred']]
    
    cmap = LinearSegmentedColormap.from_list('', colors)
    sns.heatmap(df, cmap=cmap, vmin=vmin, vmax=vmax)
    

    vminvmax 的额外计算允许根据最小值和最大值的差异动态缩放颜色图。

    使用您的输入数据框,我们得到以下热图:

    【讨论】:

    • 很好的答案!是否可以将发散的调色板应用于此解决方案,还是仅适用于 LinearSegmentedColormap?
    • 看来seaborn.diverging_palette 中心本身在(max + min) / 2 上,如果您使用我的实现,情况并非总是如此。
    • 非常感谢,还有一个问题:如何用不同的颜色(例如黑色)为 NaN 值着色?我想我应该在颜色数组中指定它,但我不确定我是否理解它的结构。有什么链接可以解释这个数组吗?
    • seaborn 自动管理nan 值,默认情况下nan 值显示为白框,更改此用法:sns.heatmap(df, cmap=cmap, vmin=vmin, vmax=vmax).set_facecolor('black')facecolor 代表背景颜色。
    • @Leonardo 如果这回答了您的问题,请将我的回复标记为“回答”
    猜你喜欢
    • 2016-01-14
    • 2016-03-29
    • 2020-10-21
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 2021-07-06
    相关资源
    最近更新 更多