Custom color palette intervals in seaborn heatmap

seaborn set color palette
sns heatmap size
seaborn calendar heatmap
seaborn correlation heatmap
seaborn 3d heatmap
sns pairplot change color
ylgnbu
seaborn color codes

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:

ok, with respect to this documentation here: https://matplotlib.org/gallery/images_contours_and_fields/custom_cmap.html#sphx-glr-gallery-images-contours-and-fields-custom-cmap-py

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.

Customizing a diverging palette heatmap, Once you understood how to make a heatmap with seaborn and how to make basic customization, you probably want to control the color palette. This is a crucial  In seaborn, when you ask for a qualitative Color Brewer palette, you’ll always get the discrete colors, but this means that at a certain point they will begin to cycle. A nice feature of the Color Brewer website is that it provides some guidance on which palettes are color blind safe.

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

#92 Control color in seaborn heatmaps – The Python Graph Gallery, Seaborn makes it easy to select and use color palettes that are suited to the kind what kind of color palette or colormap is best for a set of data without knowing functions like kdeplot() and heatmap() (along with similar matplotlib functions). This is a crucial step since the message provided by your heatmap can be different following the choice you make. Note that datacamp offers this online course to understand the basics of seaborn. Three options are possible: 1/ Sequential palette: one color only; 2/ Diverging palette: 2 c ontrasting colors; 3/ Discrete data

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)

Choosing color palettes, The Python visualization library Seaborn is based on matplotlib The basic steps to creating plots with Seaborn are: 1. Prepare Set your own color palette. Color palettes in Seaborn. Create a color palette and set it as the current color palette

[PDF] Cheat sheet Seaborn.indd, Seaborn is a Python data visualization library based on matplotlib. Tools for choosing colour palettes that faithfully reveal patterns in your data import seaborn as sns; sns.set(); # Load the example iris dataset Shows point estimates and confidence intervals using scatter plot 21. seaborn.heatmap(). #91 Custom seaborn heatmap The graph #90 explains how to make a heatmap from 3 different input formats. In this post, I describe how to customize the appearance of these heatmaps.

A Complete Python Seaborn Tutorial, Let's start by making a correlation matrix heatmap for the data set. Seaborn color palettes are just arrays of color components, so in order to map a It's a simple mapping of one interval to another: [-1, 1] → [0, 1] → (0, 255). A diverging color palette is slightly different from a sequential color palette, even if it is used to show a graduation as well. It uses a first color graduation from the minimum to a critical midpoint (orange until 0 in our example), and then use another color to go to the maximum (purple in our example).

Better Heatmaps and Correlation Matrix Plots in Python, We'll use the well known Titanic dataset (available in Seaborn), which holds Secondly, we define the labels, i.e. the name of each bin/interval; Thirdly, we the possibility to build custom attractive color palettes, and the witty way heatmap : Heatmaps are ideal to plot “rectangular data” such as matrixes. You need to set colours via palettes in Seaborn or you can pass Violinplot the colours directly via the 'palette' parameter rather than 'color'. It's all in the Seaborn docs.

Comments
  • Thank you, +1 for the custom color-dictionary, which I was not aware of, and the notion of misleading color palettes. However, in the end you basically did exactly the same thing as I did (see my solution) and which I consider a slight workaround for the issue... I am pretty surprised actually that the boundaries are not somewhat easily defineable directly in the sns.heatplot.
  • Thank you for the suggestion, I am aware of this and it would indeed be better to show the differences more clearly. There are two problems tho -- it is required to be visually 'pleasing' :), and the second, since these are not different categories I am plotting, it is better if they were differ only in the hue.