用seaborn FacetGrid绘制两个子图的映射

3

我正在尝试在一起制作两个seaborn核密度图(kdeplot)。

这里使用了三个特征(社区学校?, 经济需求指数, 学校收入估计)。唯一的分类特征"Community School?"以绿蓝色表示其级别。"经济需求指数"和"学校收入估计"分别用于两个kdeplots。

使用下面显示的代码创建的图像是我能得到的最佳结果,但它存在问题。

1) 第二个图的y轴刻度错误(它应该是一些整数刻度,就像第一个图一样)更正: kdeplot是规范化的(所有值加起来等于1),因此给定其x值,y轴是正确的。

2) 在两个图下方产生了一个额外的轴(?)

3) 我想为每个子图添加一个标题

我发现kdeplot不支持hue,所以我试图让它与FacetGrid一起工作。不确定这是否是正确的方法。如果提供更好的方法,将不胜感激。

fig, (ax1, ax2) = plt.subplots(1, 2)
fig.subplots_adjust(wspace=.8)

fg = sns.FacetGrid(df, hue='Community School?', size=3)
fg.map(sns.kdeplot, 'Economic Need Index', shade=True, ax=ax1, label='Economic Need Index')
fg.map(sns.kdeplot, 'School Income Estimate', shade=True, ax=ax2, label='School Income Estimate')
plt.show()

enter image description here

# my dataset looks like:

Community School? / Economic Need Index / School Income Estimate
0   Yes 0.919   31141.72
1   No  0.641   56462.88
2   No  0.744   44342.61
3   No  0.860   31454.00
4   No  0.730   46435.59
5   No  0.858   39415.45
6   No  0.499   43706.73
7   No  0.833   28820.67
8   No  0.849   34889.24
9   No  0.861   35545.10
10  No  0.559   40809.90
11  Yes 0.917   27881.59
12  Yes 0.832   NaN
13  No  0.791   NaN
14  No  0.362   63760.00
15  No  0.771   NaN
16  No  0.451   62519.57
17  No  0.430   57504.48
18  No  0.448   56787.20
19  No  0.764   NaN
20  No  0.610   NaN
21  No  0.257   76833.96
22  No  0.597   NaN
23  No  0.769   32817.79
24  No  0.858   26114.78
25  No  0.176   103399.19
26  No  0.101   144270.13
27  No  0.293   98455.77
28  No  0.430   88011.14
29  No  0.153   102421.46
... ... ... ...

完整数据集可以在这里找到。

2个回答

7
考虑将您的数据框进行融合,使其具有一个值列和一个指示器列,分别针对 经济需求指标学校收入估计。然后,仅使用seaborn的 FacetGrid 进行绘图,而无需使用matplotlib的 subplots() 调用,并对默认情况下的绘图属性进行调整:
long_df = pd.melt(df, id_vars='Community School?', var_name='Indicator', value_name='value')
print(long_df.head())
#       Community School?            Indicator  value
# 0                   Yes  Economic Need Index  0.919
# 1                    No  Economic Need Index  0.641
# 2                    No  Economic Need Index  0.744
# 3                    No  Economic Need Index  0.860
# 4                    No  Economic Need Index  0.730

fg = sns.FacetGrid(long_df, col='Indicator', hue='Community School?', 
                       sharex=False, sharey=False, size=4)
fg.map(sns.kdeplot, 'value', shade=True, label='Data')\
         .add_legend()\
         .set_titles("{col_name}")\
         .set_axis_labels('')
plt.show()

plt.clf()
plt.close('all')

Facet Grid Output


3

你之所以得到额外的图形,是因为在调用时FacetGrid自动打开了它自己的窗口。有关更多详细信息,请参见此问题的答案。因此,这里是一个更简单的方法可以解决问题。我添加了两行可选代码来将每种类型学校的NaN替换为平均值。

s = df.groupby(['Community School?'])['School Income Estimate'].transform('mean')
df['School Income Estimate'].fillna(s, inplace=True)

plt.subplots(1, 2)
plt.subplot(1, 2, 1)
a = sns.kdeplot(df.loc[df['Community School?'] == 'No', 'Economic Need Index'], shade=True, label='No')
b = sns.kdeplot(df.loc[df['Community School?'] == 'Yes', 'Economic Need Index'], color= 'red', shade=True, label='Yes')
plt.title('KDE of Economic Need Index')
plt.subplot(1, 2, 2)
c = sns.kdeplot(df.loc[df['Community School?'] == 'No', 'School Income Estimate'], shade=True, label='No')
d = sns.kdeplot(df.loc[df['Community School?'] == 'Yes', 'School Income Estimate'], color= 'red', shade=True, label='Yes')
plt.title('KDE of School Income Estimate')

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接