如何用Matplotlib标记用户会话时长并以星型表示Y轴活动
用户会话与活动可视化解决方案
嘿,我完全get到你的需求了——想要把用户登录到登出的会话时间段用颜色块标出来,同时在Y轴对应位置用星型标记中间的各类活动对吧?我给你整了一套可以直接运行的matplotlib实现方案,咱们一步步来:
第一步:定义数据结构与准备示例数据
首先咱们先把事件结构定义好,再生成一些模拟数据(你可以把这里的模拟数据换成你自己的真实数据):
%matplotlib inline import numpy as np import pandas as pd import matplotlib.pyplot as plt from datetime import datetime, timedelta from collections import namedtuple # 定义事件结构,包含事件类型(登录/登出/活动)、时间戳、活动名称(活动事件专属) Event = namedtuple('Event', ['event_type', 'timestamp', 'activity']) # 生成模拟的用户事件序列(替换成你自己的真实数据即可) start_time = datetime(2024, 5, 1, 8, 0) events = [ Event('login', start_time, None), Event('activity', start_time + timedelta(minutes=10), '浏览商品'), Event('activity', start_time + timedelta(minutes=25), '添加购物车'), Event('logout', start_time + timedelta(minutes=40), None), Event('login', start_time + timedelta(hours=2), None), Event('activity', start_time + timedelta(hours=2, minutes=15), '提交订单'), Event('activity', start_time + timedelta(hours=2, minutes=30), '支付'), Event('logout', start_time + timedelta(hours=2, minutes=45), None), Event('login', start_time + timedelta(hours=5), None), Event('activity', start_time + timedelta(hours=5, minutes=5), '查看订单'), Event('logout', start_time + timedelta(hours=5, minutes=20), None) ]
第二步:提取会话与活动数据
接下来咱们把登录-登出的会话时间段单独提取出来,同时把中间的活动事件也整理好:
# 提取每个会话的起止时间,给每个会话分配Y轴位置(比如会话1在y=1,会话2在y=2...) sessions = [] current_session_start = None session_idx = 1 for event in events: if event.event_type == 'login': current_session_start = event.timestamp elif event.event_type == 'logout' and current_session_start is not None: sessions.append({ 'start': current_session_start, 'end': event.timestamp, 'y': session_idx }) session_idx += 1 current_session_start = None # 筛选出所有活动事件 activity_events = [e for e in events if e.event_type == 'activity']
第三步:绘制可视化图表
现在就可以画图了,核心是用色块标记会话时间段,星型标记活动,还可以给活动加上文字说明:
# 创建画布和轴对象,设置合适的尺寸 fig, ax = plt.subplots(figsize=(12, 6)) # 绘制会话时间段的半透明色块 for sess in sessions: # 用fill_betweenx在Y轴对应位置画一个横向的色块 ax.fill_betweenx( y=[sess['y'] - 0.3, sess['y'] + 0.3], x1=sess['start'], x2=sess['end'], color='#a8d1ff', alpha=0.5, # 只在第一个会话显示图例标签,避免重复 label='会话时间段' if sess['y'] == 1 else "" ) # 绘制活动事件的星型标记 for event in activity_events: # 找到该活动所属的会话(根据时间是否在会话起止范围内) sess = next(s for s in sessions if s['start'] <= event.timestamp <= s['end']) # 用星型标记活动位置,设置大小和颜色,确保在色块上方显示 ax.scatter( x=event.timestamp, y=sess['y'], marker='*', s=150, color='#ff7f7f', zorder=5 ) # 在星号旁边添加活动名称,方便识别 ax.text( x=event.timestamp + timedelta(minutes=1), y=sess['y'], s=event.activity, va='center' ) # 设置Y轴刻度和标签,对应每个会话 ax.set_yticks([s['y'] for s in sessions]) ax.set_yticklabels([f'会话 {s["y"]}' for s in sessions]) # 设置X轴为时间格式,自动旋转标签避免重叠 ax.xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%H:%M')) plt.xticks(rotation=45) # 添加标题和坐标轴标签 ax.set_title('用户会话与活动可视化', fontsize=14) ax.set_xlabel('时间', fontsize=12) ax.set_ylabel('会话', fontsize=12) # 添加图例 ax.legend() # 调整布局,防止标签被截断 plt.tight_layout() plt.show()
自定义调整建议
你可以根据自己的需求修改这些细节:
- 颜色调整:把
fill_betweenx里的color='#a8d1ff'和scatter里的color='#ff7f7f'换成你喜欢的颜色代码 - 星号大小:修改
scatter里的s参数值,数字越大星号越大 - Y轴含义:如果是多用户的场景,可以把Y轴换成用户ID,只需要在提取会话时把
y值设为用户ID即可 - 时间格式:修改
DateFormatter里的格式字符串,比如'%Y-%m-%d %H:%M'显示完整日期时间
内容的提问来源于stack exchange,提问作者M80
相关产品推荐
相关产品推荐

