You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询:如何绘制含多聚合指标的时序堆叠面积图

搞定按小时统计的堆叠面积图(x轴按天汇总)

嘿,我太懂你这种折线图画得溜,转堆叠面积图就卡壳的感觉了!其实核心就是先把数据处理成按小时聚合、按天规整的结构,不管用Pandas+Matplotlib还是你熟悉的Bokeh,都能轻松实现。下面给你两种简洁的方案:

方案一:Pandas + Matplotlib 静态图首选

1. 先把数据捋顺

首先得确保时间戳是datetime类型,然后按小时聚合你的统计值(这里用求和,你可以换成mean()之类的,看你需求):

import pandas as pd
import matplotlib.pyplot as plt

# 假设你的数据集叫df,列是['timestamp', 'col1', 'col2', 'col3']
df['timestamp'] = pd.to_datetime(df['timestamp'])

# 按小时聚合,把每个小时的统计值合并
hourly_df = df.resample('H', on='timestamp').sum().reset_index()

# 提取日期和小时,方便后续按天整理x轴
hourly_df['date'] = hourly_df['timestamp'].dt.date
hourly_df['hour'] = hourly_df['timestamp'].dt.hour

2. 画堆叠面积图

如果想要x轴是连续的时间(按小时走),但刻度按天显示,直接用Pandas的plot.area()就行:

plt.figure(figsize=(12, 6))

# 直接调用堆叠面积图
hourly_df.set_index('timestamp')[['col1', 'col2', 'col3']].plot.area(stacked=True, alpha=0.7)

# 让x轴刻度自动适配日期,避免挤在一起
plt.gcf().autofmt_xdate()
plt.xlabel('日期')
plt.ylabel('统计值')
plt.title('一周内按小时统计的堆叠面积图')
plt.legend(title='统计列')
plt.tight_layout()
plt.show()

要是你想把每天的24小时单独对比,x轴只显示0-23点,不同日期作为不同的堆叠组,可以这么搞:

plt.figure(figsize=(12, 6))

# 遍历每一天,画当天的堆叠面积
for date in hourly_df['date'].unique():
    day_data = hourly_df[hourly_df['date'] == date].set_index('hour')[['col1', 'col2', 'col3']]
    day_data.plot.area(stacked=True, alpha=0.5, label=str(date), ax=plt.gca())

plt.xlabel('小时')
plt.ylabel('统计值')
plt.title('每天按小时统计的堆叠面积对比')
plt.legend(title='日期')
plt.tight_layout()
plt.show()

方案二:Bokeh 交互式图首选

既然你之前用过Bokeh,那直接用它的varea_stack函数就能搞定,还能做交互式的:

from bokeh.plotting import figure, show
from bokeh.models import DatetimeTickFormatter

# 预处理数据和方案一的hourly_df一致
hourly_df['timestamp'] = pd.to_datetime(hourly_df['timestamp'])

# 创建绘图对象
p = figure(x_axis_type='datetime', width=800, height=400, title='一周按小时统计的堆叠面积图')

# 定义要堆叠的列
stack_cols = ['col1', 'col2', 'col3']

# 绘制堆叠面积,指定颜色区分
p.varea_stack(stack_cols, x='timestamp', color=['#007bff', '#28a745', '#dc3545'], source=hourly_df)

# 配置x轴按天显示,旋转标签避免重叠
p.xaxis.formatter = DatetimeTickFormatter(days=['%Y-%m-%d'])
p.xaxis.major_label_orientation = 3.14/4

# 调整图例顺序(Bokeh默认堆叠顺序和图例反过来)
p.legend.items = [p.legend.items[i] for i in reversed(range(len(stack_cols)))]
p.legend.title = '统计列'

show(p)

小提醒

  • 必须先按小时聚合数据!不然原始时间戳太密集,堆叠面积会糊成一片;
  • 聚合方式选对:计数类用sum(),均值类用mean();
  • 喜欢静态图选Matplotlib,要交互(缩放、hover看数据)选Bokeh。

内容的提问来源于stack exchange,提问作者mikernova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:03:20