如何将groupby()和value_count()转换为多个饼图/条形图
问题描述
假设我有一个数据帧,并且我正在查看其中的2列(2个系列)。
使用下面的其中一列--"no_employees"
--有人能帮我弄清楚如何创建6个不同的饼图或条形图(每个NO_Employees组1个)来说明处理列中的Yes/No值的值计数吗?我将使用matplotlib
或seaborn
,只要您觉得最简单。
我使用附加的代码行生成下面的代码。
dataframe_title.groupby(['no_employees']).treatment.value_counts().
但现在我被卡住了。我要使用seaborn
吗?.plot
?这看起来应该很简单,我知道在某些情况下我可以做出subplots=True
,但是我真的很困惑。非常感谢。
no_employees treatment
1-5 Yes 88
No 71
100-500 Yes 95
No 80
26-100 Yes 149
No 139
500-1000 No 33
Yes 27
6-25 No 162
Yes 127
More than 1000 Yes 146
No 135
解决方案
- 数据可视化的目的是为了更容易地传达信息(例如,在本例中是每个类别的
'treatments'
的相对数量) - 条形图便于显示重要信息
- 每组有多少人说
'Yes'
或'No'
- 每个组的相对大小
- 每组有多少人说
- 饼图更常用于显示样本,其中样本中的组总和为100%。
- Wikipedia: Pie Chart
- 研究表明,按角度比较不如按长度比较准确,因为人们辨别差异的能力较差。
- Statisticians一般认为饼图是一种很差的信息显示方式,在科学文献中并不常见。
- 此数据不能用饼图很好地表示,因为每个公司规模都是单独的总体,这将需要正确表示6个饼图。
- 可以将数据放入饼图(如其他人所示),但这并不意味着应该将其放入饼图中。
- Wikipedia: Pie Chart
- 无论绘图类型如何,数据的形状对于绘图API都必须正确。
- 使用
pandas 1.3.0
、seaborn 0.11.1
和matplotlib 3.4.2
测试
设置测试数据帧
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np # for sample data only
np.random.seed(365)
cats = ['1-5', '6-25', '26-100', '100-500', '500-1000', '>1000']
data = {'no_employees': np.random.choice(cats, size=(1000,)),
'treatment': np.random.choice(['Yes', 'No'], size=(1000,))}
df = pd.DataFrame(data)
# set a categorical order for the x-axis to be ordered
df.no_employees = pd.Categorical(df.no_employees, categories=cats, ordered=True)
no_employees treatment
0 26-100 No
1 1-5 Yes
2 >1000 No
3 100-500 Yes
4 500-1000 Yes
pandas.DataFrame.plot()的id="plotting-with-pandas.dataframe.plot-l84f">Plotting:
- 这需要将数据帧分组以获取
.value_counts
,并使用pandas.DataFrame.unstack
进行出栈。
# to get the dataframe in the correct shape, unstack the groupby result
dfu = df.groupby(['no_employees']).treatment.value_counts().unstack()
treatment No Yes
no_employees
1-5 78 72
6-25 83 86
26-100 83 76
100-500 91 84
500-1000 78 83
>1000 95 91
# plot
ax = dfu.plot(kind='bar', figsize=(7, 5), xlabel='Number of Employees in Company', ylabel='Count', rot=0)
ax.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
使用seaborn
打印
- seaborn是matplotlib的高级接口
seaborn.barplot()
- 需要整洁(长)格式的DataFrame,方法是将DataFrame分组以获取
.value_counts
,然后使用pandas.Series.reset_index
重置索引
- 也可以使用
sns.catplot()
和kind='bar'
进行图形级界面操作
# groupby, get value_counts, and reset the index
dft = df.groupby(['no_employees']).treatment.value_counts().reset_index(name='Count')
no_employees treatment Count
0 1-5 No 78
1 1-5 Yes 72
2 6-25 Yes 86
3 6-25 No 83
4 26-100 No 83
5 26-100 Yes 76
6 100-500 No 91
7 100-500 Yes 84
8 500-1000 Yes 83
9 500-1000 No 78
10 >1000 No 95
11 >1000 Yes 91
# plot
p = sns.barplot(x='no_employees', y='Count', data=dft, hue='treatment')
p.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
p.set(xlabel='Number of Employees in Company')
seaborn.countplot()
- 使用原始数据帧
df
,不进行任何转换。 - 也可以使用
sns.catplot()
和kind='count'
进行图形级界面操作
p = sns.countplot(data=df, x='no_employees', hue='treatment')
p.legend(title='treatment', bbox_to_anchor=(1, 1), loc='upper left')
p.set(xlabel='Number of Employees in Company')
barplot
和countplot
的输出
相关文章