全部
我正在尝试使用子图函数和Seaborn
库绘制两个因子图。我可以使用下面的代码分别绘制两个图。但是,seaborn
在实际图下方生成了额外的图(请参见下图)。有没有一种方法可以避免seaborn
生成额外的空图?我尝试plt.close
来摆脱地块,但不幸的是它只关闭了1个地块
另外,我试图将图例移出情节并在图例旁边显示图例。有没有简单的方法可以做到这一点。我尝试使用legend_out
软件包中的seaborn
,但是没有用。
我的代码:
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.show()
上述代码的输出:
注意:我是python的新手,请提供您的代码说明。
数据帧的投放
#n dataframe
{'borough': {0: 'Bronx', 1: 'Brooklyn', 2: 'EWR', 3: 'Manhattan', 4: 'Queens', 5: 'Staten Island', 6: 'Unknown'}, 'pickups': {0: 50.66705042597283, 1: 534.4312687082662, 2: 0.02417683628827999, 3: 2387.253281142068, 4: 309.35482385447847, 5: 1.6018880957863229, 6: 2.0571804140650674}}
#low_pickups dataframe
{'borough': {2: 'EWR', 5: 'Staten Island', 6: 'Unknown'}, 'pickups': {2: 0.02417683628827999, 5: 1.6018880957863229, 6: 2.0571804140650674}}
答案 0 :(得分:6)
请注意,factorplot
在最新版本的seaborn中被称为'catplot'。
catplot
或factorplot
是图形级功能。这意味着它们应该在图形级而不是轴级上工作。
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])
Figure 2
的{{1}}上绘制,所以axes[0]
仍然为空。Figure 1
Figure 2
,在这里,您也告诉seaborn从sns.factorplot(x="borough", y="pickups", hue="borough", kind='bar', data=low_pickups, size=4, aspect=2,ax=axes[1])
,Figure 3
的轴上绘制。Figure 1
axes[1]
。 因此,现在剩下plt.close(2)
了,您已经将两个轴“注入”到了Figure 2
调用中,并且还有由第二次调用创建的仍然为空的Figure 1
图factorplot
,但从不发表任何内容:(。
Figure 3
现在您看到factorplot
带有2个轴,而plt.show()
带有空图。
这是在终端机中运行时的情况,在笔记本中,您可能只看到两个图形一个在另一个图形的下方,另一个图形似乎是带有三个轴的图形。
您有2个选择:
只需在Figure 1
之前关闭Figure 3
:
Figure 3
基本上,您通过提供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()
中创建图形和轴的部分短路。
可能不是factorplot
设计的目的,但是,嘿,如果它起作用了,它就起作用了……而且起作用了。
让图形级功能发挥作用并创建自己的图形。您需要做的是指定要作为列的变量。
由于似乎您有2个数据帧,Figure 1
和factorplot
,因此您应该首先从其中创建一个数据帧,其中列n
就是{{ 1}}或low_pickups
:
cat
现在,您可以使用变量n
作为列,通过一次调用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)
)来创建图形:
sns.catplot
注意:sns.factorplot
是必需的,因为默认情况下它是true,并且您基本上看不到第二个面板中的值,因为它们比第一个面板中的值小得多面板。
您可能仍需要一些样式,但我会留给您;)。
希望这对您有帮助!
答案 1 :(得分:2)
我猜这是因为FactorPlot本身使用子图。
EDIT 2019年3月10日18:43 GMT:从source code for categorical.py中确认:catplot(和factorplot)使用matplotlib子图。 @Jojo的回答完美地解释了正在发生的事情
def catplot(x=None, y=None, hue=None, data=None, row=None, col=None,
col_wrap=None, estimator=np.mean, ci=95, n_boot=1000,
units=None, order=None, hue_order=None, row_order=None,
col_order=None, kind="strip", height=5, aspect=1,
orient=None, color=None, palette=None,
legend=True, legend_out=True, sharex=True, sharey=True,
margin_titles=False, facet_kws=None, **kwargs):
... # bunch of code
g = FacetGrid(**facet_kws) # uses subplots
还有axisgrid.py源代码,其中包含FacetGrid定义:
class FacetGrid(Grid):
def __init(...):
... # bunch of code
# Build the subplot keyword dictionary
subplot_kws = {} if subplot_kws is None else subplot_kws.copy()
gridspec_kws = {} if gridspec_kws is None else gridspec_kws.copy()
# bunch of code
fig, axes = plt.subplots(nrow, ncol, **kwargs)
是的,您正在创建许多子图,但不知道它,并使用ax=...
参数弄乱了它们。
@ Jojo是对的。
还有其他一些选择:
请注意,在更高的Seaborn版本中不建议使用factorplot。
import pandas as pd
import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt
print(pd.__version__)
print(sns.__version__)
print(matplotlib.__version__)
# n dataframe
n = pd.DataFrame(
{'borough': {0: 'Bronx', 1: 'Brooklyn', 2: 'EWR', 3: 'Manhattan', 4: 'Queens', 5: 'Staten Island', 6: 'Unknown'},
'kind': {0: 'n', 1: 'n', 2: 'n', 3: 'n', 4: 'n', 5: 'n', 6: 'n'},
'pickups': {0: 50.66705042597283, 1: 534.4312687082662, 2: 0.02417683628827999, 3: 2387.253281142068,
4: 309.35482385447847, 5: 1.6018880957863229, 6: 2.0571804140650674}})
# low_pickups dataframe
low_pickups = pd.DataFrame({'borough': {2: 'EWR', 5: 'Staten Island', 6: 'Unknown'},
'kind': {0: 'low_pickups', 1: 'low_pickups', 2: 'low_pickups', 3: 'low_pickups',
4: 'low_pickups', 5: 'low_pickups', 6: 'low_pickups'},
'pickups': {2: 0.02417683628827999, 5: 1.6018880957863229, 6: 2.0571804140650674}})
new_df = n.append(low_pickups).dropna()
print(n)
print('--------------')
print(low_pickups)
print('--------------')
print(new_df)
g = sns.FacetGrid(data=new_df, col="kind", hue='kind', sharey=False)
g.map(sns.barplot, "borough", "pickups", order=sorted(new_df['borough'].unique()))
plt.show()
控制台输出:
0.24.1
0.9.0
3.0.2
borough kind pickups
0 Bronx n 50.667050
1 Brooklyn n 534.431269
2 EWR n 0.024177
3 Manhattan n 2387.253281
4 Queens n 309.354824
5 Staten Island n 1.601888
6 Unknown n 2.057180
--------------
borough kind pickups
0 NaN low_pickups NaN
1 NaN low_pickups NaN
2 EWR low_pickups 0.024177
3 NaN low_pickups NaN
4 NaN low_pickups NaN
5 Staten Island low_pickups 1.601888
6 Unknown low_pickups 2.057180
--------------
borough kind pickups
0 Bronx n 50.667050
1 Brooklyn n 534.431269
2 EWR n 0.024177
3 Manhattan n 2387.253281
4 Queens n 309.354824
5 Staten Island n 1.601888
6 Unknown n 2.057180
2 EWR low_pickups 0.024177
5 Staten Island low_pickups 1.601888
6 Unknown low_pickups 2.057180
或尝试以下操作:
g = sns.barplot(data=new_df, x="kind", y="pickups", hue='borough')#, order=sorted(new_df['borough'].unique()))
g.set_yscale('log')
我不得不使用y对数刻度,因为数据值在很大的范围内相当分散。您可以考虑进行分类(请参阅熊猫的剪裁)
编辑2019年3月10日18:43 GMT:正如@Jojo在他的回答中所述,最后一个选择确实是:
sns.catplot(data=new_df, x="borough", y="pickups", col='kind', hue='borough', sharey=False, kind='bar')
没有时间完成学习,所以一切功劳归功于他!
答案 2 :(得分:0)
我之所以来到这里,是因为我在sns.catplot
绘图网格下方的空白绘图中遇到了完全相同的问题。 @jojo的答案很好,并详细解释了所有内容。作为这些东西的新手,除了一点之外,我无法改善它。快速解决方案就是关闭sns.catplot()
创建的图形,只需在plt.close(plt.gcf())
之后直接调用 sns.catplot()
即可最轻松地实现。这样,您无需考虑要关闭的数字的数字索引。
至少以下内容对我有用,并且可以完全满足我的需求。 5个x3排列的14个不同的Catplot。没有空图,不在网格下方和网格的尽头。
cols = [ "Year Built", "Year Remod/Add", "Bsmt Full Bath", "Bsmt Half Bath",
"Full Bath", "Half Bath", "Bedroom AbvGr", "Kitchen AbvGr", "TotRms AbvGrd",
"Fireplaces", "Garage Yr Blt", "Garage Cars", "Mo Sold", "Yr Sold" ] # len 14
fig, axs = plt.subplots(5, 3, figsize = (18, 24))
for i, ax in enumerate(axs.flatten()):
if i < len(cols):
sns.catplot(x = cols[i], y = "SalePrice", data = df, ax = ax, kind = "boxen")
plt.close(plt.gcf()) # close current figure just created by catplot
else:
ax.set_axis_off() # hide empty subplot at end of grid