Custom color palette intervals in seaborn heatmap

帅比萌擦擦* 提交于 2020-06-13 06:09:50

问题


I am trying to plot a heatmap using seaborn library.

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:

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

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)


Appreciate any help.

PS: current heatmap for illustration:


回答1:


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:

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.




回答2:


I was able to find out (not very clean tho, in my opinion) solution to this, which is using 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,
  )



回答3:


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.

See also 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)


来源:https://stackoverflow.com/questions/50192121/custom-color-palette-intervals-in-seaborn-heatmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!