【发布时间】:2018-01-09 21:29:40
【问题描述】:
有没有一种方法可以使用seaborn 的sns.boxplot() 迭代地绘制数据而不会使箱线图重叠? (没有将数据集组合成一个pd.DataFrame())
背景
有时在比较不同(例如大小/形状)的数据集时,相互比较通常很有用,可以通过使用不同的共享变量(通过pd.cut() 和df.groupby(),如下所示)对数据集进行分箱来进行。
以前,我通过使用matplotlib 的ax.boxplot() 循环单独的DataFrames(通过提供y 轴位置值作为position 参数以确保箱线图不要重叠)。
示例
下面是一个简化示例,显示了使用sns.boxplot() 时的重叠图:
import seaborn as sns
import random
import pandas as pd
import matplotlib.pyplot as plt
# Get the tips dataset and select a subset as an example
tips = sns.load_dataset("tips")
variable_to_bin_by = 'tip'
binned_variable = 'total_bill'
df = tips[[binned_variable, variable_to_bin_by] ]
# Create a second dataframe with different values and shape
df2 = pd.concat( [ df.copy() ] *5 )
# Use psuedo random numbers to convey that df2 is different to df
scale = [ random.uniform(0,2) for i in range(len(df2[binned_variable])) ]
df2[ binned_variable ] = df2[binned_variable].values * scale * 5
dfs = [ df, df2 ]
# Group the data by a list of bins
bins = [0, 1, 2, 3, 4]
for n, df in enumerate( dfs ):
gdf = df.groupby( pd.cut(df[variable_to_bin_by].values, bins ) )
data = [ i[1][binned_variable].values for i in gdf]
dfs[n] = pd.DataFrame( data, index = bins[:-1])
# Create an axis for both DataFrames to be plotted on
fig, ax = plt.subplots()
# Loop the DataFrames and plot
colors = ['red', 'black']
for n in range(2):
ax = sns.boxplot( data=dfs[n].T, ax=ax, width=0.2, orient='h',
color=colors[n] )
plt.ylabel( variable_to_bin_by )
plt.xlabel( binned_variable )
plt.show()
更多细节
我意识到上面的简化示例可以通过组合 DataFrame 并将 hue 参数提供给 sns.boxplot() 来解决。
更新提供的 DataFrames 的索引也无济于事,因为随后使用了提供的最后一个 DataFrame 的 y 值。
提供kwargs 参数(例如kwargs={'positions': dfs[n].T.index})将不起作用,因为这会引发TypeError。
TypeError: boxplot() 获得了多个关键字参数值 '职位'
将sns.boxplot() 的dodge 参数设置为True 并不能解决这个问题。
【问题讨论】:
-
你需要在循环中创建plt设置,在
sns.boxplot之前和之后 -
通常的策略确实是将数据合并到一个数据帧中。为什么这里没有这个选项?
-
@Mohsen_Fatemi,请提供您推荐更新的设置?
-
@ImportanceOfBeingErnest 确实如此。我已根据您的评论更新了示例,以尝试突出显示此示例中的 DataFrame 在形状和内容上有所不同。
标签: python matplotlib plot seaborn boxplot