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

时间:2018-05-05 17:18:07

标签: python matplotlib data-visualization heatmap seaborn

我正在尝试使用seaborn库绘制heatmap

绘图功能如下所示:

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,
    )

然而,data的直方图如下所示: Histogram

现在我遇到的问题是seaborn heatmap(查看贝娄)均匀分割色标,因此大多数数据具有相同的颜色(因为数据不均匀分布)。

我无法找到如何为颜色级别设置某种间隔或边界。

假设我有以下十六进制颜色值数组:

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

有没有办法设置颜色,如

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

其中threshold_i是范围[0,1)

中的值


感谢任何帮助。

PS:当前的热图例示:

enter image description here

3 个答案:

答案 0 :(得分:1)

好的,关于此文档,请点击此处: https://matplotlib.org/gallery/images_contours_and_fields/custom_cmap.html#sphx-glr-gallery-images-contours-and-fields-custom-cmap-py

你可以创建自己的颜色词典。这些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)

生成:

enter image description here

可以做得更多(例如,对于离散跳转,只需查看文档......)但这应该回答您原来的问题 - " custom"这次包括......

但是,我必须添加我的个人观点:像这样拉伸的彩色贴图可能是令人愉悦的,但是应该注意它们不会误导观众的眼睛。

我希望这会有所帮助。

答案 1 :(得分:0)

明知在你的问题中没有解决“习惯” - 或许这有助于同时:

在众所周知的色彩映射下,在整个范围内平滑变化,还有一些更适合显示几个数据带中的小差异,例如gist_ncar

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

enter image description here

使用

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

答案 2 :(得分:0)

我能够找到(在我看来不是很干净的)解决方案,这是使用matplotlib.colors.LinearSegmentedColormap

代码如下所示:

# 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,
  )