Search code examples
seaborntransparency

to_rgba in Seaborn stripplot - Set different transparency for filling color and edgecolor


I want to set different transparencies for filling color and edgecolor in seaborn stripplot:

import seaborn as sns
from matplotlib.colors import to_rgba

tips = sns.load_dataset("tips")


sns.stripplot(x="day", y="total_bill", hue="smoker",
              data=tips,
              palette={'Yes': to_rgba('darkgreen', 0.3), 'No': to_rgba('red', 0.3)},
              edgecolor='black', linewidth=1,)

Why doesn't it work? I just want to keep black adgecolor (keep black as alpha = 1.0) but make the filling colors to be transparent (darkgreen and red to be alpha = 0.3). If I use alpha, it will make both to be transparent.

enter image description here

I can use scatterplot to achieve similar thing, but I hope I can use stripplot :

import seaborn as sns
from matplotlib.colors import to_rgba

tips = sns.load_dataset("tips")

color_dict = {'Yes': to_rgba('darkgreen', 0.1),
              'No': to_rgba('red', 0.1)}

sns.scatterplot(x="day", y="total_bill", data=tips, hue = "smoker", palette=color_dict, edgecolor='black', linewidth=1) 

The figure will be: enter image description here


Solution

  • One way to set different alpha values based on smoke = Yes/No would to use the below code. You can set different colors and alpha as required.

    import seaborn as sns
    tips = sns.load_dataset("tips")
    
    ax=sns.stripplot(x="day", y="total_bill", data=tips[tips.smoker == "Yes"], alpha = 0.3, color = 'darkgreen', edgecolor='black', linewidth=1) 
    sns.stripplot(x="day", y="total_bill", data=tips[tips.smoker == "No"], alpha = 0.3, color = 'red', edgecolor='black', linewidth=1) 
    

    Plot

    enter image description here

    EDIT

    To set the colors directly, you can set your custom palette as below and then use smoker as hue.

    # Create an array with the colors you want to use
    colors = ["red", "darkgreen"]
    # Set your custom color palette
    sns.set_palette(sns.color_palette(colors))
    #Use hue for smoker to differentiate colors
    sns.stripplot(x="day", y="total_bill", data=tips, alpha = 0.3, hue = "smoker", edgecolor='black', linewidth=1) 
    

    IF your requirement is that HAVE to use to_rgba(), then you can set it in colors and keep the alpha here as well. This is the other code...

    # Create an array with the colors you want to use
    colors = [to_rgba("red", 0.3), to_rgba("darkgreen", 0.3)]
    # Set your custom color palette
    sns.set_palette(sns.color_palette(colors))
    #Use hue for smoker to differentiate colors
    sns.stripplot(x="day", y="total_bill", data=tips, hue = "smoker", edgecolor='black', linewidth=1) 
    

    In both cases, plot will be as below.

    enter image description here

    New Requirement

    As you mentioned in the update, you are ok with the colors from scatter plot. You can write a small function to add jitter to your figure, which will achieve what you are looking for. See the update to your scatterplot code below to achieve what you are looking for.

    import seaborn as sns
    from matplotlib.colors import to_rgba
    tips = sns.load_dataset("tips")
    color_dict = {'Yes': to_rgba('darkgreen', 0.1), 'No': to_rgba('red', 0.1)}
    
    #The days are strings, convert to numbers for plotting
    Numday = {'Thur': 1, 'Fri': 2, 'Sat': 3, 'Sun' : 4}
    
    def addJitter(x): ##Function to add jitter. Adjust numbers to make it thick/thin
        return x + random.uniform(0, .3) -.15
    
    ## Convert day -> Numday which is a different number for each day
    tips['numDays'] = tips['day'].astype("string").apply(lambda x: numDays[x])
    ## Use jitter function to add jitter to each numDays
    tips['jitter'] = tips['numDays'].apply(lambda x: addJitter(x))
    
    sns.scatterplot(x= tips.jitter, y=tips.total_bill, hue = tips.smoker, palette=color_dict, edgecolor='black', linewidth=1)
    ## You will need to reset the x-axis to show the day
    plt.xticks([1,2,3,4])
    plt.gca().set_xticklabels(['Thur', 'Fri', 'Sat', 'Sun'])
    

    enter image description here