2

How can you change the legend labels on a seaborn FacetGrid using barplots and boxplots?

With scatterplots, you can do this easily:

tips = sns.load_dataset('tips')
g = sns.FacetGrid(data=tips, col='time')
g.map_dataframe(sns.scatterplot, x='total_bill', y='tip', hue='sex')
plt.legend(labels=['Men', 'Women'])

Modifying legend labels for scatterplot works as expected

However, the same code using boxplots removes the color patches from the legend:

g = sns.FacetGrid(data=tips, col='time')
g.map_dataframe(sns.boxplot, x='smoker', y='tip', hue='sex')
plt.legend(labels=['Men', 'Women'])

enter image description here

Unlike barplot itself, the FacetGrid has no legend_ property, so existing solutions for barplots like this don't easily apply.

How do you modify the legend labels without removing the color patches?

Dillon Bowen
  • 346
  • 3
  • 9

1 Answers1

0

You can do this with FacetGrid's add_legend method. When calling add_legend, the legend_data parameter maps labels to color patches. FacetGrid stores its default legend data in a _legend_data property. So all you need to do is pass a legend_data parameter with your desired labels as the keys and the FacetGrid's default _legend_data values as the values.

g = sns.FacetGrid(data=tips, col='time')
g.map_dataframe(sns.barplot, x='smoker', y='tip', hue='sex')
hue_labels = ['Men', 'Women']
g.add_legend(legend_data={
    key: value for key, value in zip(hue_labels, g._legend_data.values())
})

enter image description here

g = sns.FacetGrid(data=tips, col='time')
g.map_dataframe(sns.boxplot, x='smoker', y='tip', hue='sex')
hue_labels = ['Men', 'Women']
g.add_legend(legend_data={
    key: value for key, value in zip(hue_labels, g._legend_data.values())
})

enter image description here

Dillon Bowen
  • 346
  • 3
  • 9
  • 1
    Don't access `g._legend_data` in code that shouldn't unexpectedly break at some point when you update seaborn. – mwaskom Apr 09 '21 at 11:20