mwaskom / seaborn

Statistical data visualization in Python
https://seaborn.pydata.org
BSD 3-Clause "New" or "Revised" License
12.62k stars 1.94k forks source link

Issue with facet grid and legends #3707

Closed vsbuffalo closed 5 months ago

vsbuffalo commented 5 months ago

Here is an MRE:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
np.random.seed(1)

n_samples = 1000
data = {
    'metric': np.random.rand(n_samples),
    'method': np.random.choice(['Method A', 'Method B', 'Method C'], n_samples),
    'criterion': np.random.choice(['Criterion 1', 'Criterion 2'], n_samples),
    'category': np.random.choice(['Category X', 'Category Y'], n_samples)
}

generic_df = pd.DataFrame(data)

# Plot using Seaborn's FacetGrid
g = sns.FacetGrid(generic_df,  col='criterion', row='category', 
                  margin_titles=True, height=3, aspect=1.2)
g.map_dataframe(sns.histplot, x='metric', hue='method', bins=30, multiple='stack')
g.set_axis_labels('Metric', 'Frequency')
g.set_titles(col_template='{col_name}', row_template='{row_name}')
g.fig.subplots_adjust(top=0.89)
g.fig.suptitle('Histogram of Metric Grouped by Criterion and Category')

g.add_legend()

# Display the plot
plt.show()

I can move hue='method' over to sns.FacetGrid and the legend will display, but that changes the bar plot so it is not properly stacked.

mwaskom commented 5 months ago

FacetGrid legend relies on functions adding labeled artists to the axes which histplot does not do. Is there a reason you are not using displot here?

vsbuffalo commented 5 months ago

Thanks! I built up that approach from sns.histpolot and then added in FaceGrid after (and had AI generate a generic MRE from my actual code). I was not away that one could get displot to control the faceting. Thank you.