Search code examples
matplotlibipythonseabornfacet-grid

Is It Possible to Truncate Empty Grids in Seaborn Facetgrid?


I am writing code in a Jupyter notebook, and have a Seaborn facetgrid that I want to have 4 columns, and 3 rows. Each plot is for a different country out of a list of 10 countries. Since there are 12 total grids, and the last two are empty, is there a way to just get rid of those last two grids ? The solution of making the dimensions 5 x 2 is not an option since it is too hard to see when so many plots are scrunched together.

Code:

ucb_w_reindex_age = ucb_w_reindex[np.isfinite(ucb_w_reindex['age'])]
ucb_w_reindex_age = ucb_w_reindex_age.loc[ucb_w_reindex_age['age'] < 120]

def ageSeries(country):
    return ucb_w_reindex_age.loc[ucb_w_reindex_age['country_destination'] == country].age.fillna(value=30).resample('5d').rolling(window=3, min_periods=1).mean()

def avgAge(country):
    return ucb_w_reindex_age.loc[ucb_w_reindex_age['country_destination'] == country].age.mean()

num_plots = 10
fig, axes = plt.subplots(3, 4,figsize=(20, 15))
labels = ["01/10", "09/10", "05/11", "02/12", "10/12", "06/13", "02/14"]

list_of_dfs = [{'country': item, 'age': ageSeries(item), 'avgAge': avgAge(item)} for item in ['US', 'FR', 'AU', 'PT', 'CA', 'DE', 'ES', 'GB', 'IT', 'NL']]

colors = ['blue', 'green', 'red', 'orange', 'purple', 'blue', 'green', 'red', 'orange', 'purple']
col, row, loop = (0, 0, 0)
for obj in list_of_dfs:
    row = math.floor(loop/4)

    sns.tsplot(data=obj['age'], color=colors[loop], ax=axes[row, col])
    axes[row, col].set_title('{}'.format(full_country_names[obj['country']]))
    axes[row, col].axhline(obj['avgAge'], color='black', linestyle='dashed', linewidth=4)
    axes[row, col].set(ylim=(20, 65))
    axes[row, col].set_xticklabels(labels, rotation=0)
    axes[row, col].set_xlim(0, 335)

    if col == 0:
        axes[row, col].set(ylabel='Average Age')

    col += 1
    loop += 1

    if col == 4:
        col = 0

fig.suptitle('Age Over Time', fontsize=30)
plt.show()

Facet Grid *I know having images seems to be taboo here in S.O., but theres really not a way to put this in code.

enter image description here


Solution

  • I assume you generate your subplots with

    fig, axes = plt.subplots(3, 4,figsize=(20, 15))
    

    not seaborn.FacetGrid, as shown in your sample codes. What you need first is to somehow figure out which plots you want to get rid of and what their correct index in axes. Then you can use matplotlib.figure.Figure.delaxes() to remove subplots you don't want. Here is an example:

    import matplotlib.pyplot as plt
    
    fig, axes = plt.subplots(3, 4,figsize=(20, 15))
    fig.delaxes(axes[2, 2])
    fig.delaxes(axes[2, 3])
    plt.show()
    

    enter image description here

    Delete subplots from seaborn.FacetGrid is somewhat similar. The only minor detail is you would access axes by g.axes:

    import matplotlib.pyplot as plt
    import seaborn as sns
    
    tips = sns.load_dataset("tips")
    g = sns.FacetGrid(tips, col="time", row="smoker", sharex=False, sharey=False)
    g.fig.delaxes(g.axes[1, 1])
    plt.show()
    

    enter image description here