Seaborn Factorplot generates extra empty plots below actual plot

前端 未结 3 969
有刺的猬
有刺的猬 2020-12-09 10:10

All,

I am trying to plot two Factorplots using subplots function and Seaborn library. I was able to plot two plots separately using below code. However,

3条回答
  •  Happy的楠姐
    2020-12-09 11:04

    Note that factorplot is called 'catplot' in more recent versions of seaborn.

    catplot or factorplot are figure level functions. This means that they are supposed to work on the level of a figure and not on the level of axes.

    What is happening in your code:

    f,axes=plt.subplots(1,2,figsize=(8,4))
    
    • This creates 'Figure 1'.
    sns.factorplot(x="borough", y="pickups", hue="borough", kind='bar', data=n, size=4, aspect=2,ax=axes[0])
    
    • This creates 'Figure 2' but instead of drawing on Figure 2 you tell seaborn to draw on axes[0] from Figure 1, so Figure 2 remains empty.
    sns.factorplot(x="borough", y="pickups", hue="borough", kind='bar', data=low_pickups, size=4, aspect=2,ax=axes[1])
    
    • Now this creates yet again a figure: Figure 3 and here, too, you tell seaborn to draw on an axes from Figure 1, axes[1] that is.
    plt.close(2)
    
    • Here you close the empty Figure 2 created by seaborn.

    So now you are left with Figure 1 with the two axes you kinda 'injected' into the factorplot calls and with the still empty Figure 3 figure that was created by the 2nd call of factorplot but never sah any content :(.

    plt.show()
    
    • And now you see Figure 1 with 2 axes and the Figure 3 with an empty plot.

      This is when run in terminal, in a notebook you might just see the two figures one below the other appearing to be a figure with 3 axes.


    How to fix this:

    You have 2 options:

    1. The quick one:

    Simply close Figure 3 before plt.show():

    f,axes=plt.subplots(1,2,figsize=(8,4))
    
    sns.factorplot(x="borough", y="pickups", hue="borough", kind='bar', data=n, size=4, aspect=2,ax=axes[0])
    
    sns.factorplot(x="borough", y="pickups", hue="borough", kind='bar', data=low_pickups, size=4, aspect=2,ax=axes[1])
    plt.close(2)
    plt.close(3)
    plt.show()
    

    Basically you are short-circuiting the part of factorplot that creates a figure and axes to draw on by providing your "custom" axes from Figure 1. Probably not what factorplot was designed for, but hey, if it works, it works... and it does.

    2. The correct one:

    Let the figure level function do its job and create its own figures. What you need to do is specify what variables you want as columns.

    Since it seems that you have 2 data frames, n and low_pickups, you should first create a single data frame out of them with the column say cat that is either n or low_pickups:

    # assuming n and low_pickups are a pandas.DataFrame:
    # first add the 'cat' column for both
    n['cat'] = 'n'
    low_pickups['cat'] = 'low_pickups'
    # now create a new dataframe that is a combination of both
    comb_df = n.append(low_pickups)
    

    Now you can create your figure with a single call to sns.catplot (or sns.factorplot in your case) using the variable cat as column:

    sns.catplot(x="borough", y="pickups", col='cat', hue="borough", kind='bar', sharey=False, data=comb_df, size=4, aspect=1)
    plt.legend()
    plt.show()
    

    Note: The sharey=Falseis required as by default it would be true and you woul essentially not see the values in the 2nd panel as they are considerably smaller than the ones in the first panel.

    Version 2. then gives:

    You might still need some styling, but I'll leave this to you ;).

    Hope this helped!

提交回复
热议问题