Color markers in stripplot by a different variable than hue

5.1k views Asked by At

I have made a Seaborn stripplot on top of barplot that has experience group on the axis, grouped by two different conditions (target present or target not present) from a dataframe using the following code:

IZ_colors = ['#E1F3DC','#56B567']

ax1 = sns.barplot(data=IZ_df, x='Group', y='Time in IZ (%)', hue='Condition',
                  order=['Std_Ctrl','ELS_Ctrl','Std_CSDS','ELS_CSDS'], hue_order=['Empty','Aggressor'],
                  palette=IZ_colors)

hatches = ['','//']
# Loop over the bars
for bars, hatch in zip(ax1.containers, hatches):
    # Set a different hatch for each group of bars
    for bar in bars:
        bar.set_hatch(hatch)
        
            
sns.stripplot(data=IZ_df ,x='Group', y='Time in IZ (%)', hue='Condition', dodge=True,
              order=['Std_Ctrl','ELS_Ctrl','Std_CSDS','ELS_CSDS'], hue_order=['Empty','Aggressor'], 
              palette=IZ_colors, marker='o', size=7, edgecolor='#373737', linewidth=1, color='black',)

plt.legend(bbox_to_anchor=(1.35, 0.7))

However, I would like the markers of the stripplot to be colored by sex (not by condition like how they are now), which is another column in the dataframe. I would still like them to be grouped by hue='Condition'. Is this possible?

plot here

1

There are 1 answers

0
JohanC On BEST ANSWER

You could create two stripplots, one for each sex and draw them as the same spot. The double entries of the legend can be removed via get_legend_handles_labels() and taking a subset of the handles and the labels.

Here is an example using the titanic dataset:

import matplotlib.pyplot as plt
import seaborn as sns

titanic = sns.load_dataset('titanic')

IZ_colors = ['#E1F3DC', '#56B567']

ax1 = sns.barplot(data=titanic, x='class', y='age', hue='alive',
                  order=['First', 'Second', 'Third'], hue_order=['no', 'yes'],
                  palette=IZ_colors)

hatches = ['', '//']
for bars, hatch in zip(ax1.containers, hatches):
    for bar in bars:
        bar.set_hatch(hatch)
for sex, color in zip(['male', 'female'], ['orange', 'turquoise']):
    df_per_sex = titanic[titanic['sex'] == sex]
    sns.stripplot(data=df_per_sex, x='class', y='age', hue='alive',
                  order=['First', 'Second', 'Third'], hue_order=['no', 'yes'],
                  dodge=True, palette=[color] * 2,
                  marker='o', size=4, edgecolor='#373737', linewidth=1)
handles, labels = ax1.get_legend_handles_labels()
handles = [handles[0], handles[2]] + handles[4:]
labels = ['Male', 'Female'] + labels[4:]
ax1.legend(handles, labels, bbox_to_anchor=(1.01, 0.7), loc='upper left')
plt.tight_layout()
plt.show()

stripplot with different colors for non-hue column