如何创建具有时间序列和聚合值的堆积条形图

How to create stacked bar chart with a time series and aggregated values

我在从 Pandas 数据框(下图)创建堆积条形图时间序列时遇到困难。我想在 x 轴上有 'Date',在 y 轴上有 'Hours',每个条形图显示在 'Category'.

中每个组花费的时间

我需要使用 Pandas - Groupby 功能吗?数据框是一个样本。我有数百行从 2018 年到 2020 年的数据。

  • 有一个 to
    • 该问题的问题在于 OP 未聚合任何数据,因此该解决方案不适用于该问题。
  • 'date''group' 上使用 pandas.DataFrame.groupby,同时在 'time' 上聚合 .sum
    • .dt 提取器仅用于提取 'date' 列的 .date 部分。
    • 确保数据框的 'Date' 列格式正确 datetime dtypedf.Date = pd.to_datetime(df.Date)
  • 必须将分组数据帧 dfg 整形为正确的形式,这可以通过 pandas.DataFrame.pivot 来完成。
  • 堆叠条形图的最简单方法是使用 pandas.DataFrame.plot.bar 并使用 stacked 参数。
    • 有关所有参数,请参阅 pandas.DataFrame.plot

导入和数据转换

import pandas as pd
import matplotlib.pyplot as plt
import random  # for test data
import numpy as np  # for test data

# setup dataframe with test data
np.random.seed(365)
random.seed(365)
rows = 1100
data = {'hours': np.random.randint(10, size=(rows)),
        'group': [random.choice(['A', 'B', 'C']) for _ in range(rows)],
        'date': pd.bdate_range('2020-11-24', freq='h', periods=rows).tolist()}
df = pd.DataFrame(data)

# display(df.head())
   hours group                date
0      2     C 2020-11-24 00:00:00
1      4     B 2020-11-24 01:00:00
2      1     C 2020-11-24 02:00:00
3      5     A 2020-11-24 03:00:00
4      2     B 2020-11-24 04:00:00

# use groupby on df
dfg = df.groupby([df.date.dt.date, 'group'])['hours'].sum().reset_index()

# pivot the dataframe into the correct format
dfp = dfg.pivot(index='date', columns='group', values='hours')

# display(dfp.head())
group        A   B   C
date                  
2020-11-24  49  25  29
2020-11-25  62  18  57
2020-11-26  42  77   4
2020-11-27  34  43  17
2020-11-28  28  53  23
  • 更简洁地说,groupby 和 pivot 步骤可以用 .pivot_table 代替,它既重塑又聚合
      使用
    • index=df.date.dt.date,因此索引不包括时间部分,因为正在汇总一整天的数据。
dfp = df.pivot_table(index=df.date.dt.date, columns='group', values='hours', aggfunc='sum')

情节

# plot the pivoted dataframe
dfp.plot.bar(stacked=True, figsize=(10, 6), ylabel='Hours', xlabel='Date', title='Sum of Daily Category Hours')
plt.legend(title='Category', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show()

  • 每天都会有一个条形图,这就是条形图刻度的工作原理,因此如果有很多日期,图可能会很宽。
  • 考虑使用 pandas.DataFrame.barh
dfp.plot.barh(stacked=True, figsize=(6, 10), title='Sum of Daily Category Hours')
plt.legend(title='Category', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.xlabel('Hours')
plt.ylabel('Date')
plt.show()

  • OP 指出有 2018 年到 2020 年的数据,这意味着可能有超过 700 天的数据,这转化为条形图中的 700 多个条。
  • 标准线图可能是正确显示数据的最佳选择。
dfp.plot(figsize=(10, 6))
plt.show()