如何在多列上绘制 groupby 的值
Posted
技术标签:
【中文标题】如何在多列上绘制 groupby 的值【英文标题】:How to plot the values of a groupby on multiple columns 【发布时间】:2022-01-11 06:48:00 【问题描述】:我有一个类似于以下的数据集:
import pandas as pd
data = 'Country': ['Spain', 'Italy', 'France', 'Germany', 'Portugal', 'Greece', 'UK', 'Spain', 'Italy', 'France', 'Germany', 'Portugal', 'Greece', 'UK', 'Spain', 'Italy', 'France', 'Germany', 'Portugal', 'Greece', 'UK'],
'Date': ['Jan 2020', 'Jan 2020', 'Jan 2020', 'Jan 2020', 'Jan 2020', 'Jan 2020', 'Jan 2020', 'Feb 2020', 'Feb 2020', 'Feb 2020', 'Feb 2020', 'Feb 2020', 'Feb 2020', 'Feb 2020', 'Dec 2020', 'Dec 2020', 'Dec 2020', 'Dec 2020', 'Dec 2020', 'Dec 2020', 'Dec 2020'],
'Sales': [20000, 30000, 10000, 10000, 30000, 10000, 10000, 50000, 40000, 30000, 20000, 30000, 10000, 10000, 60000, 70000, 80000, 10000, 30000, 10000, 10000]
df = pd.DataFrame(data)
Country Date Sales
0 Spain Jan 2020 20000
1 Italy Jan 2020 30000
2 France Jan 2020 10000
3 Germany Jan 2020 10000
4 Portugal Jan 2020 30000
5 Greece Jan 2020 10000
6 UK Jan 2020 10000
7 Spain Feb 2020 50000
8 Italy Feb 2020 40000
9 France Feb 2020 30000
10 Germany Feb 2020 20000
11 Portugal Feb 2020 30000
12 Greece Feb 2020 10000
13 UK Feb 2020 10000
14 Spain Dec 2020 60000
15 Italy Dec 2020 70000
16 France Dec 2020 80000
17 Germany Dec 2020 10000
18 Portugal Dec 2020 30000
19 Greece Dec 2020 10000
20 UK Dec 2020 10000
我想可视化一年中各个国家/地区的销售额变化情况,因此我想显示 7 个直方图(每个国家/地区一个)。对于每个图,“日期”将在 x 轴上,“销售”值在 y 轴上。此外,还需要标识国家/地区的标题以及 x-label、y-label。
我尝试了之前讨论中的几个选项,但这些选项都不符合我想要实现的目标。我尝试了以下方法:
df.groupby('Country').hist(column='Sales', grid= False, figsize=(2,2))
df['Sales'].hist(grid=True, by=one_year_df['Country'])
df.groupby('Country').hist(grid= False, figsize=(2,2))
df.reset_index().pivot('index','Country','Sales').hist(grid=False, bins=12)
grouped = df.groupby('Country')
ncols=2
nrows = int(np.ceil(grouped.ngroups/ncols))
fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(12,12), sharey=False)
for (key, ax) in zip(grouped.groups.keys(), axes.flatten()):
grouped.get_group(key).plot(ax=ax)
ax.legend()
plt.show()
但是,这些选项都没有让我能够设置“日期”列,而且似乎无法按照我的意愿设置 x 轴、y 轴,因此,绘图是毫无意义。
我还发现了另一段代码,似乎考虑了所有变量,但结果仍然不如预期:
fig, ax = plt.subplots(figsize=(15,7))
df.groupby(['Country']).sum()['Sales'].plot(ax=ax)
ax.set_xlabel('Date')
ax.set_ylabel('Sales')
欢迎任何 cmets 或建议。谢谢。
【问题讨论】:
【参考方案1】: 对于每个图,“日期”将在 x 轴上,“销售”值在 y 轴上。最好用线图或条形图显示。直方图本质上是条形图(就可视化而言)。 使用pd.to_datetime
将'Date'
列转换为日期时间
使用pivot_table
和aggfun='sum'
重塑数据框
使用pandas.DataFrame.plot
绘图,它使用matplotlib
作为默认绘图后端
请参阅How to give a pandas/matplotlib bar graph custom colors 为线条或条形指定不同的颜色。
List of named colors
Choosing Colormaps
如有必要,请参阅此answer 以通过许多子图改进子图大小/间距。
import pandas as pd
import matplotlib.pyplot as plt
# convert the column to a datetime dtype
df.Date = pd.to_datetime(df.Date).dt.date
# reshape the dataframe
dfp = df.pivot_table(index='Date', columns='Country', values='Sales', aggfunc='sum')
# plot
ax = dfp.plot(figsize=(8, 5))
ax.legend(bbox_to_anchor=(1, 1.02), loc='upper left')
如果绘制条形图,会出现拥挤的混乱,因为每行数据都会有一个条形图。
ax = dfp.plot(kind='bar', subplots=True, figsize=(14, 12), layout=(2, 4), rot=0, legend=False)
【讨论】:
以上是关于如何在多列上绘制 groupby 的值的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 groupby 和聚合将 pyspark 数据框中的行与多列连接起来