Search code examples
pythonmatplotlibseabornfacet-grid

Why is my graph not showing every Month? Facetgrid, Seaborn


My sample dataset is the following:

dataset = {
    "ClientId": [
        10, 20, 20, 20, 10, 5, 3, 7, 5, 20, 12, 5, 
        3, 20, 5, 8, 10, 9, 7, 20, 21, 5, 3, 10,
    ],
    "Year": [
        2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019,
        2019, 2019, 2019, 2019, 2020, 2020, 2020, 2020,
        2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020,
    ],
    "Month": [
        "Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", 
        "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", 
        "Mai", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
    ],
    "Sector": [
        "A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C", 
        "A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C",
    ],
    "Quantity": [
        100, 50, 25, 30, 40, 50, 200, 600, 20, 40, 100, 20, 50, 
        400, 250, 300, 125, 75, 90, 10, 225, 550, 450, 55,     
    ],     
    "Regions": [
        "Europe", "Asia", "Africa", "Africa", "Other", "Asia", 
        "Africa", "Other", "America", "America", "Europe", 
        "Europe", "Other", "Europe", "Asia", "Africa", "Asia", 
        "Europe", "Other", "Africa", "Europe", "Asia", "Africa", 
        "Europe",
    ],
}
df = pd.DataFrame(data=dataset)

I want to produce a Facetgrid of bar plots for each Year and Sector. I have managed to create the plot:

g = sns.FacetGrid(df, col='Year', row='Sector', margin_titles=True)
g.map_dataframe(sns.barplot, x='Month', y='Quantity', color='orange')
g.set_axis_labels('Months','Quantity')

The Problem: The bar plots don't display every Months, only a few. What I would like is to see one bar per Month but I'm stuck.

The graph looks like this currently: enter image description here


Solution

  • You can force seaborn to use all the columns by providing the column order to map_dataframe:

    g = sns.FacetGrid(df, col="Year", row="Sector", margin_titles=True)
    g.map_dataframe(
        sns.barplot, x="Month", y="Quantity", color="orange", order=df["Month"].unique()
    )
    g.set_axis_labels("Months", "Quantity")
    g.set_xticklabels(rotation=90)
    

    Alternatively, and a better option in my opinion, is to use sns.catplot like so. This still returns a facetgrid, but doesn't require extra fiddling.

    g = sns.catplot(
        x="Month",
        y="Quantity",
        col="Year",
        row="Sector",
        data=df,
        kind="bar",
        height=2.5,
        aspect=0.8,
        color="orange",
        margin_titles=True,
    )
    g.set_xticklabels(rotation=90)
    

    Which produces:
    enter image description here