如何用Seaborn Objects美化时序数据图表并自定义Y轴颜色?
按钮按压时序图表美化:Y轴日期配色与睡眠区域添加
我正在美化按钮按压时序数据的图表,提升可读性以便分析时段内的按压频率。目前已生成初步图表,但数据量较大导致可读性欠佳,现有代码及示例数据如下:
date_list = ['2024/07/27, 22:00:34', '2024/07/27, 21:51:34', '2024/07/27, 21:29:00', '2024/07/27, 21:15:21', '2024/07/27, 21:07:55', '2024/07/28, 20:03:56', '2024/07/28, 20:36:41', '2024/07/28, 20:22:58', '2024/07/28, 20:09:17', '2024/07/28, 20:04:49', '2024/07/29, 20:02:07', '2024/07/29, 19:37:25', '2024/07/29, 17:51:23', '2024/07/29, 17:47:29', '2024/07/29, 17:00:28', '2024/07/30, 16:42:06', '2024/07/30, 16:11:29', '2024/07/30, 16:08:18', '2024/07/30, 15:50:38', '2024/07/30, 15:36:45', '2024/07/30, 15:23:23', '2024/07/31, 15:12:04', '2024/07/31, 15:08:42', '2024/07/31, 15:00:46', '2024/07/31, 14:41:30'] compare_date = datetime.date(1066, 1, 1) compare_time = datetime.time(12, 00, 00) dt_df = pd.DataFrame(data_list,columns=["bt_dates"]) dt_df["bt_dates"] = dt_df["bt_dates"].apply(lambda x: datetime.strptime(x, "%Y/%m/%d, %H:%M:%S")) dt_df["time"] = dt_df["bt_dates"].apply(lambda x: datetime.combine(compare_date, x.time())) dt_df["date"] = dt_df["bt_dates"].apply(lambda x: datetime.combine(x.date(), compare_time)) f, ax = pyplot.subplots() ( seaborn_objects.Plot(dt_df, x="time", y="date") .add(seaborn_objects.Dash(), seaborn_objects.Dodge(), orient="y") .scale(y=seaborn_objects.Temporal().tick(upto=100)) .on(ax) .plot() ) ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M', ))
下一步希望根据工作日/周末将Y轴日期设为红色,并添加代表睡眠/清醒时段的灰色区域,但刚接触Seaborn Objects,不清楚如何修改Y轴颜色。
实现方案
1. 标记工作日/周末
先在DataFrame中新增列,区分日期属于工作日还是周末:
import datetime as dt dt_df["is_weekend"] = dt_df["bt_dates"].dt.weekday >= 5 # 周六(5)、周日(6)标记为周末
2. 自定义Y轴刻度颜色
Seaborn Objects侧重数据可视化语法,轴样式精细控制需结合Matplotlib的轴对象实现:
# 绘制图表后遍历Y轴刻度标签 for tick in ax.get_yticklabels(): # 解析刻度对应的日期 tick_date = dt.datetime.strptime(tick.get_text(), "%Y-%m-%d").date() # 周末刻度设为红色 if tick_date.weekday() >= 5: tick.set_color("red")
3. 添加睡眠时段灰色区域
使用Matplotlib的ax.axvspan()添加垂直半透明区域,覆盖睡眠时段(示例为22:00-次日6:00):
# 定义睡眠时段的时间点 sleep_start = dt.datetime.combine(compare_date, dt.time(22, 0)) sleep_end = dt.datetime.combine(compare_date, dt.time(6, 0)) # 分两段添加跨天的睡眠区域 ax.axvspan(sleep_start, dt.datetime(1066,1,1,23,59,59), color="gray", alpha=0.2) ax.axvspan(dt.datetime(1066,1,1,0,0), sleep_end, color="gray", alpha=0.2)
完整修改后的代码
import pandas as pd import datetime as dt import matplotlib.pyplot as plt import matplotlib.dates as mdates from seaborn import objects as so date_list = ['2024/07/27, 22:00:34', '2024/07/27, 21:51:34', '2024/07/27, 21:29:00', '2024/07/27, 21:15:21', '2024/07/27, 21:07:55', '2024/07/28, 20:03:56', '2024/07/28, 20:36:41', '2024/07/28, 20:22:58', '2024/07/28, 20:09:17', '2024/07/28, 20:04:49', '2024/07/29, 20:02:07', '2024/07/29, 19:37:25', '2024/07/29, 17:51:23', '2024/07/29, 17:47:29', '2024/07/29, 17:00:28', '2024/07/30, 16:42:06', '2024/07/30, 16:11:29', '2024/07/30, 16:08:18', '2024/07/30, 15:50:38', '2024/07/30, 15:36:45', '2024/07/30, 15:23:23', '2024/07/31, 15:12:04', '2024/07/31, 15:08:42', '2024/07/31, 15:00:46', '2024/07/31, 14:41:30'] compare_date = dt.date(1066, 1, 1) compare_time = dt.time(12, 00, 00) dt_df = pd.DataFrame(date_list, columns=["bt_dates"]) dt_df["bt_dates"] = dt_df["bt_dates"].apply(lambda x: dt.datetime.strptime(x, "%Y/%m/%d, %H:%M:%S")) dt_df["time"] = dt_df["bt_dates"].apply(lambda x: dt.datetime.combine(compare_date, x.time())) dt_df["date"] = dt_df["bt_dates"].apply(lambda x: dt.datetime.combine(x.date(), compare_time)) # 新增周末标记列 dt_df["is_weekend"] = dt_df["bt_dates"].dt.weekday >= 5 f, ax = plt.subplots(figsize=(10,6)) ( so.Plot(dt_df, x="time", y="date") .add(so.Dash(), so.Dodge(), orient="y") .scale(y=so.Temporal().tick(upto=100)) .on(ax) .plot() ) ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) # 修改Y轴刻度颜色 for tick in ax.get_yticklabels(): tick_date = dt.datetime.strptime(tick.get_text(), "%Y-%m-%d").date() if tick_date.weekday() >=5: tick.set_color("red") # 添加睡眠时段灰色区域 sleep_start = dt.datetime.combine(compare_date, dt.time(22,0)) sleep_end = dt.datetime.combine(compare_date, dt.time(6,0)) ax.axvspan(sleep_start, dt.datetime(1066,1,1,23,59,59), color="gray", alpha=0.2) ax.axvspan(dt.datetime(1066,1,1,0,0), sleep_end, color="gray", alpha=0.2) plt.legend(["按压记录", "睡眠时段"]) plt.tight_layout() plt.show()
说明
- Seaborn Objects专注于数据可视化的语法封装,轴样式的精细调整仍需依赖Matplotlib的原生API,直接操作
ax对象是最直接的方式。 - 睡眠区域分两段添加是为了覆盖跨天的时间范围,半透明灰色既突出时段,又不会遮挡按压数据。
内容的提问来源于stack exchange,提问作者linkey apiacess
相关产品推荐
相关产品推荐

