Search code examples
pythonbar-chartseabornfacet-grid

python facetgrid with sns.barplot and map; target no overlapping group bars


I am currently implementing a code for facetgrid with subplots of barplots with two different groups ('type'), respectively. I am intending to get a plot, where the different groups are not stacked and not overlapping. I am using following code

g = sns.FacetGrid(data,
            col='C',
            hue = 'type',
            sharex=False,
            sharey=False,
            size=7,
            palette=sns.color_palette(['red','green']),
            )
g = g.map(sns.barplot, 'A', 'B').add_legend()

The data is a pandas long format df with following example structure:

data=pd.DataFrame({'A':['X','X','Y','Y','X','X','Y','Y'],
               'B':[0,1,2,3,4,5,6,7],
               'C':[1,1,1,1,2,2,2,2],
               'type':['ctrl','cond1','ctrl','cond1','ctrl','cond1','ctrl','cond1']}
                )

In the created barplots I get now fully overlapping barplots of the two groups, thus ctrlis missing, see below. However, I am intending to get neighbouring non-overlapping bars each. How to achieve that? My real code has some more bars per plot, where you can see overlapping colors (here fully covered)

enter image description here


Solution

  • I think you want to provide the hue argument to the barplot, not the FacetGrid. Because the grouping takes place within the (single) barplot, not on the facet's level.

    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import seaborn as sns
    
    data=pd.DataFrame({'A':['X','X','Y','Y','X','X','Y','Y'],
                   'B':[0,1,2,3,4,5,6,7],
                   'C':[1,1,1,1,2,2,2,2],
                   'type':['ctrl','cond1','ctrl','cond1','ctrl','cond1','ctrl','cond1']})
    
    g = sns.FacetGrid(data,
                col='C',
                sharex=False,
                sharey=False,
                height=4)
    g = g.map(sns.barplot, 'A', 'B', "type", 
              hue_order=np.unique(data["type"]), 
              order=["X", "Y"], 
              palette=sns.color_palette(['red','green']))
    g.add_legend()
    
    plt.show()
    

    enter image description here