I can't figure out how to vary both hue and style in a seaborn FacetGrid
mapped to lineplot
, and still end up with a legend. Setup:
import numpy as np
import seaborn as sns
# add variables "group" and "stim_order" to the fMRI dataset, for demo purposes
df = sns.load_dataset('fmri')
df['group'] = df['subject'].map(lambda subj: int(subj.lstrip('s')) % 2)
df['stim_order'] = df['subject'].map({subj: np.random.choice([0, 1])
for subj in df['subject'].unique()})
The following would be ideal, but isn't implemented (FacetGrid
has no "style" param):
g = sns.FacetGrid(data=df, row='region', col='event', hue='group', style='stim_order')
g.map(sns.lineplot, 'timepoint', 'signal')
This next approach also doesn't work, because apparently kwargs passed to FacetGrid.map()
cannot be references to columns in the data:
g = sns.FacetGrid(data=df, row='region', col='event', hue='group')
g.map(sns.lineplot, 'timepoint', 'signal', style='stim_order')
# fails with ValueError: Could not interpret input 'stim_order'
I can work around these limitations by not specifying "hue" when setting up the FacetGrid
, and adding a new column "size" to the data, so that I can pass all the data-related parameters as positional args. But then I get no legend:
df['size'] = 1
g = sns.FacetGrid(data=df, row='region', col='event')
g.map(sns.lineplot, 'timepoint', 'signal', 'group', 'size', 'stim_order')
Is there a way to get a plot like this, but that has a brief legend_out
containing the hue
and style
mappings?
You can use g.map_dataframe
instead of g.map
and get the behaviour you wish.
Using your code would result in:
g = sns.FacetGrid(data=df, row='region', col='event', hue='group')
g.map_dataframe(sns.lineplot, 'timepoint', 'signal', style='stim_order')