Changing color scale in seaborn bar plot

Question:

I would like to use seaborn bar plot for my data with a color scale according to the values in the Y-axis. For example, from this image, color changes from left to right according to a color palette:

enter image description here

But what I actually wanted is this same color scheme but in "vertical" instead of "horizontal". Is this possible? I’ve searched and tried to set the hue parameter to the Y-axis but it doesn’t seem to work, how can I do it?

Asked By: MrPedru22

||

Answers:

Here a solution:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

sns.set(style="whitegrid", color_codes=True)

titanic = sns.load_dataset("titanic")
data = titanic.groupby("deck").size()  # data underlying bar plot in question

pal = sns.color_palette("Greens_d", len(data))
rank = data.argsort().argsort()  # http://stackoverflow.com/a/6266510/1628638
sns.barplot(x=data.index, y=data, palette=np.array(pal[::-1])[rank])

plt.show()

Here the output:
bar plot

Note: the code currently assigns different (adjacent) colors to bars with identical height. (Not a problem in the sample plot.) While it would be nicer to use the same color for identical-height bars, the resulting code would likely make the basic idea less clear.

Answered By: Ulrich Stern

The double usage of the argsort from Ulrich’s answer didn’t work for me. But this did:

rank = [int((max(array)-elem)*len(df)*0.75/(max(array)+1)) for elem in array] 
pal = sea.color_palette("Reds_r",len(df))

Example seaborn barchart with bar heights according to y values:

mentioned seaborn barchart

Answered By: molecman

This solution uses the values as indices into the color palette; so that similar values get similar colors:

import seaborn as sns
import numpy as np


def colors_from_values(values, palette_name):
    # normalize the values to range [0, 1]
    normalized = (values - min(values)) / (max(values) - min(values))
    # convert to indices
    indices = np.round(normalized * (len(values) - 1)).astype(np.int32)
    # use the indices to get the colors
    palette = sns.color_palette(palette_name, len(values))
    return np.array(palette).take(indices, axis=0)


x = np.arange(10)
y = np.random.random(10)
sns.barplot(x, y, palette=colors_from_values(y, "YlOrRd"))

Resulting in:

This

Answered By: Abdo B.

Here a solution:

import seaborn as sns
import numpy as np
import pandas as pd

def colors_from_values(values: pd.Series, palette_name:str, ascending=True):
    '''Returns a seaborn palette reordered by value
    Parameters:
    values: pd.Series
    palette_name:str, Seaborn valid palette name
    ascending: bool, optional color sort order
    '''
    # convert to indices
    values = values.sort_values(ascending=ascending).reset_index()
    indices = values.sort_values(by=values.columns[0]).index
    # use the indices to get the colors
    palette = sns.color_palette(palette_name, len(values))
    return np.array(palette).take(indices, axis=0)

s = pd.Series([123456, 123457, 122345, 95432],
              index=pd.Index([2018, 2019, 2020, 2021], name='Year'))


sns.barplot(x=s.index, y=s.values, palette=colors_from_values(s, "rocket_r"))

Results:
Plot

Answered By: mserves

The following worked for me

pal = sns.color_palette("YlOrBr", len(df_1))
array = df_1['Count']
rank = [int((max(array)-elem)*len(df_1)*0.75/(max(array)+1)) for elem in array]

sns.barplot(x = df_1.index, y = 'Count', data = df_1, 
palette=np.array(pal[::-1])[rank]);
plt.xticks(rotation = 90)  # rotate the xticks by 90 degree. 
plt.show()
Answered By: ARPAN DAS
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.