pythonmatplotlibseaborn

Seaborn: can I add a "second hue" (or similar) within a stripplot with dodge=True


Let's say I have a plot that looks like so:

import numpy as np
df = sns.load_dataset('iris')
dfm = pd.melt(df, id_vars=["species"])
dfm = dfm.query('variable in ["sepal_length", "sepal_width"]')
sns.stripplot(data=dfm, x="species", y="value", hue="variable", dodge=True)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2)

enter image description here

Let's also say there's another column with important info in my data, such as "potency".

dfm['potency'] = np.random.randint(1, 6, dfm.shape[0])

I would like to highlight the potency corresponding to each point in my plot with darkening colors (high potency -> darker). Is this possible?

I know that hue='potency' would do just this but then I could not use dodge to separate the data into sepal_width and and sepal_length chunks.


Solution

  • You could overlay multiple stripplots with different alphas:

    start, end = dfm['potency'].agg(['min', 'max'])
    for k, v in dfm.groupby('potency'):
        sns.stripplot(data=v.assign(variable=v['variable']+f' / potency={k}'),
                      x="species", y="value", hue="variable", dodge=True,
                      alpha=(k-start+1)/(end-start+1)
                     )
    plt.legend(bbox_to_anchor=(1.05, 1), loc=2)
    

    Output:

    enter image description here

    A variant with multiple colors in a paired palette:

    pal = sns.color_palette("Paired")
    
    for i, (k, v) in enumerate(dfm.groupby('potency')):
        sns.stripplot(data=v.assign(variable=v['variable']+f' / potency={k}'),
                      x="species", y="value", hue="variable", dodge=True,
                      palette=pal[2*i:2*(i+1)]
                     )
    plt.legend(bbox_to_anchor=(1.05, 1), loc=2)
    

    Output:

    enter image description here