简体   繁体   English

seaborn 热图中的自定义调色板间隔

[英]Custom color palette intervals in seaborn heatmap

I am trying to plot a heatmap using seaborn library.我正在尝试使用 seaborn 库绘制热图

The plotting function looks like this:绘图函数如下所示:

def plot_confusion_matrix(data, labels, **kwargs):
    """Visualize confusion matrix as a heat map."""
    col_map = kwargs.get('color_palette', sns.light_palette('navy', n_colors=5, as_cmap=False))

    sns.heatmap(
        vmin=0.0,
        vmax=1.0,
        data=data,
        cmap=col_map,
        xticklabels=labels,
        yticklabels=labels,
        linewidths=0.75,
    )

The histogram of the data , however, looks like this:然而, data的直方图看起来像这样: 直方图

Now the issue I am struggling with is that seaborn heatmap(view bellow) splits evenly the color scale and hence most of the data has the same color (since the data is not evenly distributed).现在我正在努力解决的问题是 seaborn 热图(查看波纹管)均匀地分割色标,因此大多数数据具有相同的颜色(因为数据分布不均匀)。

I was not able to find out how to set some sort of intervals or boundaries for the color levels.我无法找到如何为颜色级别设置某种间隔或边界。

Suppose I have the following array of hex color values:假设我有以下十六进制颜色值数组:

['#e5e5ff', '#acacdf', '#7272bf', '#39399f', '#000080']

Is there a way to set up a color such as有没有办法设置颜色,例如

[(threshold_0, hex_0), (threshold_1, hex_1), ..., (threshold_n, hex_n)]

where threshold_i is a value in range [0, 1)其中threshold_i是 [0, 1) 范围内的值


Appreciate any help.感谢任何帮助。

PS: current heatmap for illustration: PS:用于说明的当前热图:

在此处输入图片说明

With respect to this documentation here , you could create your own color-dictionary.关于此处的文档,您可以创建自己的颜色词典。 These dicts have to be of rgb-values, so I wrote a first test function to generate one from Hex_colors and your desired thresholds:这些 dicts 必须是 rgb 值,所以我写了第一个测试函数来从 Hex_colors 和你想要的阈值生成一个:

def NonLinCdict(steps, hexcol_array):
    cdict = {'red': (), 'green': (), 'blue': ()}
    for s, hexcol in zip(steps, hexcol_array):
        rgb =matplotlib.colors.hex2color(hexcol)
        cdict['red'] = cdict['red'] + ((s, rgb[0], rgb[0]),)
        cdict['green'] = cdict['green'] + ((s, rgb[1], rgb[1]),)
        cdict['blue'] = cdict['blue'] + ((s, rgb[2], rgb[2]),)
    return cdict

hc = ['#e5e5ff', '#acacdf', '#7272bf', '#39399f', '#000080']
th = [0, 0.1, 0.5, 0.9, 1]

cdict = NonLinCdict(th, hc)
cm = mc.LinearSegmentedColormap('test', cdict)

plt.figure()
sns.heatmap(
        vmin=0.0,
        vmax=1.0,
        data=data,
        cmap=cm,
        linewidths=0.75)

which generates:它产生:

在此处输入图片说明

There can be even more done (towards discrete jumps for example, just have a look at the docs...) but this should answer your original question - "custom" included this time...还可以做更多的事情(例如,针对离散跳转,只需查看文档...)但这应该可以回答您的原始问题-这次包括“自定义”...

However, I have to add my personal opinion: Colormaps which are stretched like these here might be 'pleasing', but one should pay attention that they are not misleading the eye of the viewer.但是,我必须补充一下我的个人意见:像这样拉伸的颜色图在这里可能会“令人愉悦”,但应该注意它们不会误导观众的眼睛。

I hope this helps.我希望这有帮助。

I was able to find out (not very clean tho, in my opinion) solution to this, which is using matplotlib.colors.LinearSegmentedColormap .我能够找到(在我看来不是很干净)解决方案,它使用matplotlib.colors.LinearSegmentedColormap

The code looks like this:代码如下所示:

# NOTE: jupyter notebook mode
%matplotlib inline

import seaborn as sns
from matplotlib.colors import LinearSegmentedColormap

boundaries = [0.0, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0]  # custom boundaries

# here I generated twice as many colors, 
# so that I could prune the boundaries more clearly
hex_colors = sns.light_palette('navy', n_colors=len(boundaries) * 2 + 2, as_cmap=False).as_hex()
hex_colors = [hex_colors[i] for i in range(0, len(hex_colors), 2)]

colors=list(zip(boundaries, hex_colors))

custom_color_map = LinearSegmentedColormap.from_list(
    name='custom_navy',
    colors=colors,
)

 sns.heatmap(
        vmin=0.0,
        vmax=1.0,
        data=data,
        cmap=custom_color_map,
        xticklabels=labels,
        yticklabels=labels,
        linewidths=0.75,
  )

Knowingly not addressing the "custom" in your question - perhaps this helps in the meantime:故意不解决您的问题中的“习惯” - 也许这在此期间有所帮助:

Beneath well known colormaps which change smoothly over the whole range, there are also a few which are suited better to show small differences in several bands of data, gist_ncar for example.在众所周知的在整个范围内平滑变化的颜色图下面,还有一些更适合显示多个数据带中的微小差异,例如gist_ncar

See also https://matplotlib.org/examples/color/colormaps_reference.html另见https://matplotlib.org/examples/color/colormaps_reference.html

在此处输入图片说明

created with创建于

sns.heatmap(vmin=0.0, vmax=1.0, data=data,  cmap='gist_ncar', linewidths=0.75)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM