如何修复 seaborn 热图颜色映射,当数值范围较广时。

huangapple go评论64阅读模式
英文:

How to fix seaborn heatmap color mapping when values are in wide range

问题

我有一个包含0-9范围内的6个唯一值的数据框架。我想为每个值分配特定的颜色,但映射对我不起作用。

这是我的数据框架的样子:

cmap_new = {0: '#faf5f5', 1: '#ff0303', 6: '#1f78b4', 7: '#b2df8a', 8: '#33a02c', 9: '#fb9a99'}
cmap = ListedColormap([cmap_new[i] for i in cmap_new.keys()])
ax = sns.heatmap(data=tmp_df, cmap=cmap, yticklabels=True, xticklabels=False, linewidths=1, square=True, annot=True)

我的图表看起来像这样:

如何修复 seaborn 热图颜色映射,当数值范围较广时。

在我的数据中,尽管我没有值[2-5],它们被分配了一种颜色。我想修复这个问题,只为cmap_new字典中的键分配颜色。

有人可以帮助我吗?

英文:

I have a dataframe with 6 unique values in range(0-9). I want to assign specif color to each value but mapping is not working for me.

This is how my dataframe looks like:

如何修复 seaborn 热图颜色映射,当数值范围较广时。

cmap_new = {0: '#faf5f5', 1: '#ff0303', 6: '#1f78b4', 7: '#b2df8a', 8: '#33a02c', 9: '#fb9a99'}
cmap = ListedColormap([cmap_new[i] for i in cmap_new.keys()])
ax = sns.heatmap(data=tmp_df, cmap=cmap, yticklabels=True, xticklabels=False,linewidths=1,square=True,annot=True)

My plot looks like this:

如何修复 seaborn 热图颜色映射,当数值范围较广时。

In my data, though I dont have values [2-5], they are assigned a color. I want to fix this problem and assign colors only to keys in the cmap_new dictionary.

Can anyone help me with this?

答案1

得分: 1

你可以使用BoundaryNorm来为每个数值分配颜色。需要额外的一个值,因为7个边界定义了6个颜色区域。为了获得一个漂亮的颜色条,刻度可以移动到每个区域的中心。

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, BoundaryNorm
import pandas as pd

cmap_new = {0: '#faf5f5', 1: '#ff0303', 6: '#1f78b4', 7: '#b2df8a', 8: '#33a02c', 9: '#fb9a99'}
keys = sorted(cmap_new.keys())
keys += [max(keys) + 1]
tmp_df = pd.DataFrame(np.random.choice(keys, size=(8, 7)),
                      index=['Zoros', 'Lyra', 'Elara', 'Drakor', 'Astra', 'Mystalin', 'Terra', 'Vora'])
cmap = ListedColormap([cmap_new[k] for k in keys[:-1]])
norm = BoundaryNorm(keys, ncolors=len(keys) - 1)
ax = sns.heatmap(data=tmp_df, cmap=cmap, norm=norm,
                 yticklabels=True, xticklabels=False, linewidths=1, square=True, annot=True)
ax.collections[0].colorbar.set_ticks([(k1 + k2) / 2 for k1, k2 in zip(keys[:-1], keys[1:])], labels=keys[:-1])
plt.show()

如何修复 seaborn 热图颜色映射,当数值范围较广时。

英文:

You can use a BoundaryNorm to assign a color to each of the values used. An extra value is needed, as 7 boundaries define 6 color regions. In order to get a nice colorbar, the ticks can be moved to the centers of each region.

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, BoundaryNorm
import pandas as pd

cmap_new = {0: '#faf5f5', 1: '#ff0303', 6: '#1f78b4', 7: '#b2df8a', 8: '#33a02c', 9: '#fb9a99'}
keys = sorted(cmap_new.keys())
keys += [max(keys) + 1]
tmp_df = pd.DataFrame(np.random.choice(keys, size=(8, 7)),
                      index=['Zoros', 'Lyra', 'Elara', 'Drakor', 'Astra', 'Mystalin', 'Terra', 'Vora'])
cmap = ListedColormap([cmap_new[k] for k in keys[:-1]])
norm = BoundaryNorm(keys, ncolors=len(keys) - 1)
ax = sns.heatmap(data=tmp_df, cmap=cmap, norm=norm,
                 yticklabels=True, xticklabels=False, linewidths=1, square=True, annot=True)
ax.collections[0].colorbar.set_ticks([(k1 + k2) / 2 for k1, k2 in zip(keys[:-1], keys[1:])], labels=keys[:-1])
plt.show()

如何修复 seaborn 热图颜色映射,当数值范围较广时。

huangapple
  • 本文由 发表于 2023年7月11日 01:18:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76655959.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定