pandas 两组的箱线图
Boxplot by two groups in pandas
我有以下数据集:
df_plots = pd.DataFrame({'Group':['A','A','A','A','A','A','B','B','B','B','B','B'],
'Type':['X','X','X','Y','Y','Y','X','X','X','Y','Y','Y'],
'Value':[1,1.2,1.4,1.3,1.8,1.5,15,19,18,17,12,13]})
df_plots
Group Type Value
0 A X 1.0
1 A X 1.2
2 A X 1.4
3 A Y 1.3
4 A Y 1.8
5 A Y 1.5
6 B X 15.0
7 B X 19.0
8 B X 18.0
9 B Y 17.0
10 B Y 12.0
11 B Y 13.0
我想为每个 Group
创建箱线图(示例中有两个),并在每个图中按类型显示。我试过这个:
fig, axs = plt.subplots(1,2,figsize=(8,6), sharey=False)
axs = axs.flatten()
for i, g in enumerate(df_plots[['Group','Type','Value']].groupby(['Group','Type'])):
g[1].boxplot(ax=axs[i])
- 结果为
IndexError
,因为循环试图创建 4 个图。
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-12-8e1150950024> in <module>
3
4 for i, g in enumerate(df[['Group','Type','Value']].groupby(['Group','Type'])):
----> 5 g[1].boxplot(ax=axs[i])
IndexError: index 2 is out of bounds for axis 0 with size 2
然后我试了这个:
fig, axs = plt.subplots(1,2,figsize=(8,6), sharey=False)
axs = axs.flatten()
for i, g in enumerate(df_plots[['Group','Type','Value']].groupby(['Group','Type'])):
g[1].boxplot(ax=axs[i], by=['Group','Type'])
但是不,我有同样的问题。预期结果应该只有两个图,并且每个图的每种类型都有一个盒须图。这是这个想法的草图:
拜托,任何帮助将不胜感激,使用此代码我可以控制数据的某些方面,而我无法使用 seaborn。
import seaborn as sns
sns.catplot(data=df, kind='box', col='Group', x='Type', y='Value', hue='Type', sharey=False, height=4)
眼前的问题是您的 groupby
操作 returns 四个元素(AX、AY、BX、BY),您正试图单独绘制这些元素。您尝试使用 ax=axs[i]
... 但 i
运行s 0-3,而您的扁平化结构中只有这两个元素。没有 axs[2]
或 axs[3]
,这会引发给定的 运行 时间异常。
您需要以一种或另一种方式解决引用问题。
我们可以使用 groupby boxplot
为每个 Group
创建子图,然后用 Type
:
分隔每个 boxplot
fig, axes = plt.subplots(1, 2, figsize=(8, 6), sharey=False)
df_plots.groupby('Group').boxplot(by='Type', ax=axes)
plt.show()
或者不用subplots
直接通过函数调用传递参数:
axes = df_plots.groupby('Group').boxplot(by='Type', figsize=(8, 6),
layout=(1, 2), sharey=False)
plt.show()
数据和导入:
import pandas as pd
from matplotlib import pyplot as plt
df_plots = pd.DataFrame({
'Group': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'],
'Type': ['X', 'X', 'X', 'Y', 'Y', 'Y', 'X', 'X', 'X', 'Y', 'Y', 'Y'],
'Value': [1, 1.2, 1.4, 1.3, 1.8, 1.5, 15, 19, 18, 17, 12, 13]
})
作为,眼前的问题是你的groupby()
returns四组(AX,AY,BX,BY),所以先修复索引,然后清理一个更多问题:
- 将
axs[i]
更改为 axs[i//2]
,将第 0 组和第 1 组放在 axs[0]
上,将第 2 组和第 3 组放在 axs[1]
上。
- 添加
positions=[i]
以并排放置箱线图而不是堆叠。
- 绘图后设置
title
和 xticklabels
(我不知道如何在主循环中执行此操作)。
for i, g in enumerate(df_plots.groupby(['Group', 'Type'])):
g[1].boxplot(ax=axs[i//2], positions=[i])
for i, ax in enumerate(axs):
ax.set_title('Group: ' + df_plots['Group'].unique()[i])
ax.set_xticklabels(['Type: X', 'Type: Y'])
请注意,里程可能因版本而异:
matplotlib.__version__
pd.__version__
confirmed working
3.4.2
1.3.1
confirmed not working
3.0.1
1.2.4
我有以下数据集:
df_plots = pd.DataFrame({'Group':['A','A','A','A','A','A','B','B','B','B','B','B'],
'Type':['X','X','X','Y','Y','Y','X','X','X','Y','Y','Y'],
'Value':[1,1.2,1.4,1.3,1.8,1.5,15,19,18,17,12,13]})
df_plots
Group Type Value
0 A X 1.0
1 A X 1.2
2 A X 1.4
3 A Y 1.3
4 A Y 1.8
5 A Y 1.5
6 B X 15.0
7 B X 19.0
8 B X 18.0
9 B Y 17.0
10 B Y 12.0
11 B Y 13.0
我想为每个 Group
创建箱线图(示例中有两个),并在每个图中按类型显示。我试过这个:
fig, axs = plt.subplots(1,2,figsize=(8,6), sharey=False)
axs = axs.flatten()
for i, g in enumerate(df_plots[['Group','Type','Value']].groupby(['Group','Type'])):
g[1].boxplot(ax=axs[i])
- 结果为
IndexError
,因为循环试图创建 4 个图。
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-12-8e1150950024> in <module>
3
4 for i, g in enumerate(df[['Group','Type','Value']].groupby(['Group','Type'])):
----> 5 g[1].boxplot(ax=axs[i])
IndexError: index 2 is out of bounds for axis 0 with size 2
然后我试了这个:
fig, axs = plt.subplots(1,2,figsize=(8,6), sharey=False)
axs = axs.flatten()
for i, g in enumerate(df_plots[['Group','Type','Value']].groupby(['Group','Type'])):
g[1].boxplot(ax=axs[i], by=['Group','Type'])
但是不,我有同样的问题。预期结果应该只有两个图,并且每个图的每种类型都有一个盒须图。这是这个想法的草图:
拜托,任何帮助将不胜感激,使用此代码我可以控制数据的某些方面,而我无法使用 seaborn。
import seaborn as sns
sns.catplot(data=df, kind='box', col='Group', x='Type', y='Value', hue='Type', sharey=False, height=4)
眼前的问题是您的 groupby
操作 returns 四个元素(AX、AY、BX、BY),您正试图单独绘制这些元素。您尝试使用 ax=axs[i]
... 但 i
运行s 0-3,而您的扁平化结构中只有这两个元素。没有 axs[2]
或 axs[3]
,这会引发给定的 运行 时间异常。
您需要以一种或另一种方式解决引用问题。
我们可以使用 groupby boxplot
为每个 Group
创建子图,然后用 Type
:
boxplot
fig, axes = plt.subplots(1, 2, figsize=(8, 6), sharey=False)
df_plots.groupby('Group').boxplot(by='Type', ax=axes)
plt.show()
或者不用subplots
直接通过函数调用传递参数:
axes = df_plots.groupby('Group').boxplot(by='Type', figsize=(8, 6),
layout=(1, 2), sharey=False)
plt.show()
数据和导入:
import pandas as pd
from matplotlib import pyplot as plt
df_plots = pd.DataFrame({
'Group': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'],
'Type': ['X', 'X', 'X', 'Y', 'Y', 'Y', 'X', 'X', 'X', 'Y', 'Y', 'Y'],
'Value': [1, 1.2, 1.4, 1.3, 1.8, 1.5, 15, 19, 18, 17, 12, 13]
})
作为groupby()
returns四组(AX,AY,BX,BY),所以先修复索引,然后清理一个更多问题:
- 将
axs[i]
更改为axs[i//2]
,将第 0 组和第 1 组放在axs[0]
上,将第 2 组和第 3 组放在axs[1]
上。 - 添加
positions=[i]
以并排放置箱线图而不是堆叠。 - 绘图后设置
title
和xticklabels
(我不知道如何在主循环中执行此操作)。
for i, g in enumerate(df_plots.groupby(['Group', 'Type'])):
g[1].boxplot(ax=axs[i//2], positions=[i])
for i, ax in enumerate(axs):
ax.set_title('Group: ' + df_plots['Group'].unique()[i])
ax.set_xticklabels(['Type: X', 'Type: Y'])
请注意,里程可能因版本而异:
matplotlib.__version__ |
pd.__version__ |
|
---|---|---|
confirmed working | 3.4.2 | 1.3.1 |
confirmed not working | 3.0.1 | 1.2.4 |