Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在seaborn中以箱线图的形式迭代绘制不同的数据(不重叠)?_Python_Matplotlib_Plot_Seaborn_Boxplot - Fatal编程技术网

Python 如何在seaborn中以箱线图的形式迭代绘制不同的数据(不重叠)?

Python 如何在seaborn中以箱线图的形式迭代绘制不同的数据(不重叠)?,python,matplotlib,plot,seaborn,boxplot,Python,Matplotlib,Plot,Seaborn,Boxplot,是否有一种方法可以使用seaborn迭代地绘制数据,而不会使箱线图重叠?(无需将数据集合并为单个数据集) 背景 有时,在比较不同(例如大小/形状)数据集时,相互比较通常是有用的,可以通过使用不同的共享变量(通过和,如下所示)对数据集进行组合 以前,我使用matplotlib循环单独的数据帧(通过提供y轴位置值作为位置参数,以确保箱线图不重叠),在同一轴上以箱线图的形式重复绘制这些“装箱”数据 示例 下面是一个简化示例,显示了使用sns.boxplot()时中的重叠图: 更多细节 我意识到上面的

是否有一种方法可以使用
seaborn
迭代地绘制数据,而不会使箱线图重叠?(无需将数据集合并为单个数据集)

背景

有时,在比较不同(例如大小/形状)数据集时,相互比较通常是有用的,可以通过使用不同的共享变量(通过和,如下所示)对数据集进行组合

以前,我使用
matplotlib
循环单独的数据帧(通过提供y轴位置值作为
位置
参数,以确保箱线图不重叠),在同一轴上以箱线图的形式重复绘制这些“装箱”数据

示例

下面是一个简化示例,显示了使用
sns.boxplot()
时中的重叠图:

更多细节

我意识到上面的简化示例可以通过组合数据帧并向
sns.boxplot()
提供
hue
参数来解决

更新提供的数据帧的索引也没有帮助,因为随后将使用最后提供的数据帧中的y值

提供
kwargs
参数(例如
kwargs={'positions':dfs[n].T.index}
)将不起作用,因为这会引发
TypeError

TypeError:boxplot()为关键字参数获取了多个值 “职位”

sns.boxplot()
dodge
参数设置为
True
并不能解决这个问题。

有趣的是,我提出的“hack”可以在这里应用

这使代码有点复杂,因为seaborn希望使用色调嵌套的是长格式数据帧而不是宽格式数据帧

# Get the tips dataset and select a subset as an example
tips = sns.load_dataset("tips")
df = tips[['total_bill',   'tip'] ]

# Group the data by 
bins = [0, 1, 2, 3, 4]
gdf = df.groupby( pd.cut(df['tip'].values, bins ) )
data = [ i[1]['total_bill'].values  for i in gdf]
df = pd.DataFrame( data , index = bins[:-1]).T
dfm = df.melt() # create a long-form database
dfm.loc[:,'dummy'] = 'dummy'

# Create a second, slightly different, DataFrame
dfm2 = dfm.copy()
dfm2.value = dfm.value*2
dfs = [ dfm, dfm2 ]
colors = ['red', 'black']
hue_orders = [['dummy','other'], ['other','dummy']]

# Create an axis for both DataFrames to be plotted on
fig, ax = plt.subplots()

# Loop the DataFrames and plot
for n in range(2):
    ax = sns.boxplot( data=dfs[n], x='value', y='variable', hue='dummy', hue_order=hue_orders[n], ax=ax, width=0.2, orient='h', 
                      color=colors[n] )
ax.legend_.remove()
plt.show()

您需要在sns前后的循环中创建plt设置。boxplot通常的策略实际上是将数据合并到单个数据帧中。为什么这里没有这个选项?@Mohsen_Fatemi,请给出您建议更新的设置?@ImportanceOfBeingErnest。我已经在你的评论之后更新了这个示例,试图强调这个示例中的数据帧在形状和内容上有所不同。谢谢Diziet!你的例子和a给了我我想要的东西。
# Get the tips dataset and select a subset as an example
tips = sns.load_dataset("tips")
df = tips[['total_bill',   'tip'] ]

# Group the data by 
bins = [0, 1, 2, 3, 4]
gdf = df.groupby( pd.cut(df['tip'].values, bins ) )
data = [ i[1]['total_bill'].values  for i in gdf]
df = pd.DataFrame( data , index = bins[:-1]).T
dfm = df.melt() # create a long-form database
dfm.loc[:,'dummy'] = 'dummy'

# Create a second, slightly different, DataFrame
dfm2 = dfm.copy()
dfm2.value = dfm.value*2
dfs = [ dfm, dfm2 ]
colors = ['red', 'black']
hue_orders = [['dummy','other'], ['other','dummy']]

# Create an axis for both DataFrames to be plotted on
fig, ax = plt.subplots()

# Loop the DataFrames and plot
for n in range(2):
    ax = sns.boxplot( data=dfs[n], x='value', y='variable', hue='dummy', hue_order=hue_orders[n], ax=ax, width=0.2, orient='h', 
                      color=colors[n] )
ax.legend_.remove()
plt.show()