背景
一批产品分成3组,共测试两次,每次每组测试的结果又有不同的分组,想画出3组产品在两次测试的不同结果,需要用到分组的堆积柱状图。
数据信息
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'Group': ['g1','g1','g1','g1','g1','g1','g1','g1','g2','g2','g2','g2','g2','g2','g2','g2','g3','g3','g3','g3','g3','g3','g3','g3'],'date': ['2019-03','2019-03','2019-03','2019-03','2019-04', '2019-04','2019-04','2019-04','2019-03','2019-03','2019-03','2019-03','2019-04', '2019-04','2019-04','2019-04','2019-03','2019-03','2019-03','2019-03','2019-04', '2019-04','2019-04','2019-04'],'Code': ['A0','A1','A2','A3','A0','A1','A2','A3','A0','A1','A2','A3','A0','A1','A2','A3','A0','A1','A2','A3','A0','A1','A2','A3'],
'value': [8,0,0,0,6,0,1,1,0,0,0,18,9,0,0,9,0,0,0,36, 28,5,0,3]})
print(df)
方法1 seaborn
import seaborn as sns
sns.catplot(kind='bar', data=df, col='date', x='Group', y='value', hue='Code')
图像如下,可以看出一些信息,但不是我想要的。
方法2 plt.plot
df.groupby(['Group','date','Code']).value.sum().unstack().plot(kind='bar', stacked=True, figsize=(10, 4))
图表如下,这个基本符合我的要求了,每两个柱子为一组,进行对比。
方法3 使用参考资料的方法创建分组的条形图
import numpy as np
import matplotlib.pyplot as plt
labels=df['Group'].drop_duplicates() # set the dates as labels
x0 = np.arange(len(labels)) # create an array of values for the ticks that can perform arithmetic with width (w)
# create the data groups with a dict comprehension and groupby
data = {''.join(k): v for k, v in df.groupby(['date', 'Code'])}
# build the plots
subs = df.date.unique()
stacks = len(subs) # how many stacks in each group for a tick location
business = df.Code.unique()
# set the width
w = 0.35
# this needs to be adjusted based on the number of stacks; each location needs to be split into the proper number of locations
x1 = [x0 - w/stacks, x0 + w/stacks]
fig, ax = plt.subplots()
for x, sub in zip(x1, subs):
bottom = 0
for bus in business:
height = data[f'{sub}{bus}'].value.to_numpy()
ax.bar(x=x, height=height, width=w, bottom=bottom, label=sub + '_' + bus)
bottom += height
ax.set_xticks(x0)
_ = ax.set_xticklabels(labels)
plt.legend(loc='upper left')
这个也满足了要求,就是图标有点丑,或许可以加个判断,如果值为0,就不用画图了。
结语
如上,使用3种方法完成绘制。
我同样在Tableau上尝试了一下,发现实现特别简单,只需要把Group和date拖入列,value拖入行,最后把Code拖入颜色就完成了。
参考资料
How to create grouped and stacked bars – Python (tutorialink.com)