0
votes

I have created a set of raincloud plot distributions that follow a specific color scheme (Set2 from seaborn). I wanted to have my countplot match the colors by group listed (example: male and female counts would be green for the diet group, m:f counts would be pink for mod-pa etc). However I'm unable to align the color palette to both the x variable and the hue. It seems countplot will only color based on the hue.

Color scheme of raincloud plots Color scheme of bar plot

I have tried using set_colors to manipulate which bars to change color, I've also tried mapping colors based on conditionals like below, but nothing seems to be working.

ax = sns.countplot(x="Group", hue="Sex", data=df)
ax[0].set_color('r')

TypeError: 'AxesSubplot' object does not support indexing


value=(df['Group']=='DIET') & (df['Sex']=='Female')

df['color']= np.where( value==True , "#9b59b6", "#3498db")

ax = sns.countplot(x="Group", hue="Sex", data=df, color=df['color'])

TypeError: 'Series' objects are mutable, thus they cannot be hashed

Full code

import pandas as pd

import numpy as np

import seaborn as sns

df = pd.DataFrame({"Sex" : np.random.choice(["Male",  "Female"], size=1310, p=[.65, .35]),
                   "Group" : np.random.choice(["DIET", "MOD-PA", "HIGH-PA"],size=1310)})

# Unique category labels: 'Diet', 'MOD-PA'...
color_labels = df['Group'].unique()

# List of color palette to use
rgb_values = sns.color_palette("Set2", 6)

# Map label to color palette

color_map = dict(zip(color_labels, rgb_values))

ax = sns.countplot(x="Group", hue="Sex", data=df, palette=df['Group'].map(color_map))

Even though I'm mapping to the x variable (group) it still maps onto the hue variable (sex)

2

2 Answers

5
votes

Instead of using the color parameter, you can use the palette parameter in countplot. You can define a palette as a list of colors(in HEX code) and pass it or can directly give a list.

    sns.countplot(x = df['Dependent'], palette=['#432371',"#FAAE7B"]);
2
votes

I've solved the issue thought I feel it is a very messy solution and anything that seems cleaner would be much appreciated.

    f, axes = plt.subplots(1, 3, figsize=(5,5))
    sns.despine()
    DIET_df=df.loc[df['Group'] == 'DIET']
    MOD_df=df.loc[df['Group'] == 'MOD-PA']
    HIGH_df=df.loc[df['Group'] == 'HIGH-PA']
    ax = sns.countplot(x='Group', hue='Sex', data=DIET_df, palette= ["#7fcdbb",                 "#edf8b1"], ax=axes[0])
    ax1=sns.countplot(x='Group', hue='Sex', data=MOD_df, palette=["#fc9272",         "#fee0d2"], ax=axes[1])
    ax1.set(yticklabels=[])
    ax1.set_yticks([])
    ax1.set(ylabel=' ')
    ax1.spines["left"].set_visible(False)
    ax2=sns.countplot(x='Group', hue='Sex', data=HIGH_df, palette=["#bcbddc", "#efedf5"], ax=axes[2])
    ax2.set(yticklabels=[])
    ax2.set(ylabel=' ')
    ax2.set_yticks([])
    ax2.spines["left"].set_visible(False)