Seaborn 热力图颜色映射

4

我有一个数据框 df,其值从0到x(x为整数且没有固定值),在我的例子中x=10

我想用cmap 'Reds'映射热图,但是当数值为0时,不应该是白色而是绿色 '#009933'

import seaborn as sns # matplotlib inline 
import random
data = []
for i in range(10):
    data.append([random.randrange(0, 11, 1) for _ in range(10)])
df = pd.DataFrame(data)

fig, ax = plt.subplots(figsize = (12, 10)) 
# cmap = [????]
ax = sns.heatmap(df, cmap='Reds', linewidths = 0.005, annot = True, cbar=True) 
                            
plt.show()

这里输入图片描述 我该怎么做?


2个回答

4
作为对接受的答案的替代方案,您也可以将vmin设置为略高于0,并使用set_under定义超出范围值的颜色:
import copy
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

cmap = copy.copy(plt.get_cmap("Reds"))
cmap.set_under('#009933')
sns.heatmap(np.random.randint(0,10,(10,10)), cmap=cmap, lw=0.005, annot=True, vmin=1e-5)

在这里输入图片描述

默认情况下,colorbar 中不会显示 under 颜色。要修改 colorbar,请使用例如 sns.heatmap(..., cbar_kws={'extend':'min', 'extendrect':True})。有关这些参数的解释,请参见 colorbar 文档


1
您可以使用 cbar_kw={'extend':'min', 'extendrect':'True} 来显示底部颜色。例如,参见 seaborn don't give color in heatmap if cell value is higher than 0.05 - JohanC
@Stef SO不允许我在5分钟后编辑评论。无论如何,SO更喜欢答案更加自包含,所以我更新了你的答案。 - JohanC
@JohanC 哦,我明白了。我只是想要给你应有的赞扬。非常感谢你的编辑! - Stef

2
您可以使用matplotlib.colors中的LinearSegmentedColormap。首先必须找到最大值,本例中为10,然后使用它来创建一个颜色变量,该变量从绿色开始,然后转换为标准的“Reds”颜色集。在使用seaborn制作热图时,请将colorbar设置为False,并使用matplotlib单独制作一个colorbar。
此代码改编自这里
import matplotlib.pyplot as plt
import matplotlib.colors as cl
import seaborn as sns
import pandas as pd
import numpy as np
import random

data = []
for i in range(10):
    data.append([random.randrange(0, 11, 1) for _ in range(10)])
df = pd.DataFrame(data)

fig, ax = plt.subplots(figsize = (12, 10)) 
cmap_reds = plt.get_cmap('Reds')
num_colors = 11
colors = ['#009933'] + [cmap_reds(i / num_colors) for i in range(1, num_colors)]
cmap = cl.LinearSegmentedColormap.from_list('', colors, num_colors)
ax = sns.heatmap(df, cmap=cmap, vmin=0, vmax=num_colors, square=True, cbar=False, annot = True)
cbar = plt.colorbar(ax.collections[0], ticks=range(num_colors + 1))
cbar.set_ticks(np.linspace(0, num_colors, 2*num_colors+1)[1::2])
cbar.ax.set_yticklabels(range(num_colors))
plt.show()

这是输出结果:

在此输入图像描述


@JohanC 哦,我明白了,干得好!我会编辑我的回答! - DapperDuck
为了使色条刻度位于每个单元格的中心,您可以尝试使用 cbar.set_ticks(np.linspace(0, num_colors, 2*num_colors+1)[1::2]); cbar.ax.set_yticklabels(range(num_colors)) - JohanC
@JohanC 我更新了我的答案,加入了您的评论中提到的代码。 - DapperDuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接