Python Seaborn定制范围热图

Python Seaborn定制范围热图,python,pandas,seaborn,heatmap,Python,Pandas,Seaborn,Heatmap,我需要根据以下要求构建定制的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&

我需要根据以下要求构建定制的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_信息

id      A      B    C
            
min     0.5    6    850
max     0.9    10   880
df
中的每个值都应该在
df_info
中定义的范围内
例如,如果列
A
的值在0.5和0.9之间,则视为正常值。超出范围的值应使用自定义热图着色

特别是:

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

Q:我不知道如何用标准的热图来实现这一点,我甚至不确定我能用热图图来实现这一点。有什么建议吗?

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

  • 0
    1
    之间,如果值介于
    df_info
    min
    max
  • 低于
    0
    如果值低于
    df_info
    min
  • 高于
    1
    如果值高于
    df_info
    max
要规范化数据帧,请使用:

对于df中的列:
df[col]=(df[col]-df_info[col]['min'])/(df_info[col]['max']-df_info[col]['min'])
最后,要创建颜色编码的热图,请使用:

导入seaborn作为sns
从matplotlib.colors导入LinearSegmentedColormap
vmin=df.min().min()
vmax=df.max().max()
颜色=[[0,'暗蓝色'],
[-vmin/(vmax-vmin),“白色”],
[(1-vmin)/(vmax-vmin),“白色”],
[1,'darkred']]
cmap=线性分段颜色映射。来自列表(“”,颜色)
sns.heatmap(df,cmap=cmap,vmin=vmin,vmax=vmax)
使用
vmin
vmax
的附加计算允许根据与最小值和最大值的差异动态缩放颜色贴图

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

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

  • 0
    1
    之间,如果值介于
    df_info
    min
    max
  • 低于
    0
    如果值低于
    df_info
    min
  • 高于
    1
    如果值高于
    df_info
    max
要规范化数据帧,请使用:

对于df中的列:
df[col]=(df[col]-df_info[col]['min'])/(df_info[col]['max']-df_info[col]['min'])
最后,要创建颜色编码的热图,请使用:

导入seaborn作为sns
从matplotlib.colors导入LinearSegmentedColormap
vmin=df.min().min()
vmax=df.max().max()
颜色=[[0,'暗蓝色'],
[-vmin/(vmax-vmin),“白色”],
[(1-vmin)/(vmax-vmin),“白色”],
[1,'darkred']]
cmap=线性分段颜色映射。来自列表(“”,颜色)
sns.heatmap(df,cmap=cmap,vmin=vmin,vmax=vmax)
使用
vmin
vmax
的附加计算允许根据与最小值和最大值的差异动态缩放颜色贴图

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

回答得很好!是否可以将发散调色板应用于此解决方案,或者它仅适用于LinearSegmentedColormap?似乎
seaborn.Divering_调色板
center本身位于
(max+min)/2
上,如果您使用我的实现,这并不总是您的情况。非常感谢,另一个问题:如何使用不同的颜色(例如黑色)为NaN值着色?我想我应该在颜色数组中指定它,但我不确定我是否理解它的结构。解释此数组的任何链接?
seaborn
自动管理
nan
值,默认情况下
nan
值显示为白色框,以更改此用法:
sns.heatmap(df,cmap=cmap,vmin=vmin,vmax=vmax)。设置面颜色(“黑色”)
facecolor
代表背景色。@Leonardo如果这回答了你的问题,请将我的回答标记为“答案”非常好的答案!是否可以将发散调色板应用于此解决方案,或者它仅适用于LinearSegmentedColormap?似乎
seaborn.Divering_调色板
center本身位于
(max+min)/2
上,如果您使用我的实现,这并不总是您的情况。非常感谢,另一个问题:如何使用不同的颜色(例如黑色)为NaN值着色?我想我应该在颜色数组中指定它,但我不确定我是否理解它的结构。解释此数组的任何链接?
seaborn
自动管理
nan
值,默认情况下
nan
值显示为白色框,以更改此用法:
sns.heatmap(df,cmap=cmap,vmin=vmin,vmax=vmax)。设置面颜色(“黑色”)
facecolor
代表背景色。@Leonardo如果这回答了您的问题,请将我的回答标记为“答案”