如何使用Plotly与Pandas创建此类纵轴时间线图表?
用Plotly + Pandas实现纵轴时间线的睡眠时长图
核心思路
你要的是横向条形图的变种——把时间维度放在纵轴,日期放在横轴,每个日期对应一段代表睡眠区间的横向条形,本质是把常规甘特图的轴做了互换。下面是具体实现步骤:
1. 数据预处理
首先要把睡眠的入睡/起床时间转换成Plotly能识别的数值格式(比如一天中的小时数),同时处理跨天的情况(比如22:00入睡次日6:00起床)。
示例代码:
import pandas as pd import plotly.graph_objects as go # 构造示例数据(替换成你的真实数据) data = { 'date': ['2024-05-01', '2024-05-02', '2024-05-03', '2024-05-04'], 'bed_time': ['2024-05-01 22:15:00', '2024-05-02 21:45:00', '2024-05-03 22:30:00', '2024-05-04 23:00:00'], 'wake_time': ['2024-05-02 06:30:00', '2024-05-03 07:00:00', '2024-05-04 06:15:00', '2024-05-05 07:30:00'] } df = pd.DataFrame(data) # 转换为datetime类型 df['bed_time'] = pd.to_datetime(df['bed_time']) df['wake_time'] = pd.to_datetime(df['wake_time']) # 计算入睡/起床时间的小时数(跨天的起床时间加24小时,保证时间轴连续) df['bed_hour'] = df['bed_time'].dt.hour + df['bed_time'].dt.minute/60 df['wake_hour'] = df['wake_time'].dt.hour + df['wake_time'].dt.minute/60 df['wake_hour'] += (df['wake_time'].dt.date != df['bed_time'].dt.date) * 24 # 计算睡眠时长 df['sleep_duration'] = df['wake_hour'] - df['bed_hour']
2. 绘制图表
用Plotly的横向条形图,通过base参数设置条形的起始位置(入睡时间),y参数设置条形长度(睡眠时长),再自定义纵轴刻度让时间显示更直观。
示例代码:
# 定义纵轴刻度(覆盖20:00到次日09:00的范围) y_ticks = list(range(20, 33)) y_tick_labels = [f"{t if t<24 else t-24:02d}:00" for t in y_ticks] fig = go.Figure() # 逐个添加每日睡眠的条形 for _, row in df.iterrows(): fig.add_trace(go.Bar( x=[row['date']], y=[row['sleep_duration']], base=[row['bed_hour']], orientation='h', marker_color='#2E8B57', width=0.6 # 调整条形宽度 )) # 配置图表样式 fig.update_layout( title='每日睡眠时段', xaxis_title='日期', yaxis_title='时间', yaxis=dict( tickmode='array', tickvals=y_ticks, ticktext=y_tick_labels, range=[19, 33], # 锁定纵轴范围,避免自动缩放 autorange=False ), showlegend=False, bargap=0.4 # 调整日期之间的间距 ) fig.show()
简化版(用Plotly Express)
如果追求代码简洁,也可以用Plotly Express实现:
import plotly.express as px fig = px.bar(df, x='date', y='sleep_duration', base='bed_hour', orientation='h') fig.update_layout( yaxis=dict( tickmode='array', tickvals=y_ticks, ticktext=y_tick_labels, range=[19, 33] ) ) fig.show()
关键注意事项
- 跨天处理:必须给次日的起床时间小时数加24,否则纵轴会出现时间回退的问题。
- 刻度自定义:把超过24的小时数转换成
00:00、01:00这类格式,符合日常时间阅读习惯。 - 样式调整:可以根据需求修改条形颜色、宽度、轴标签、标题等细节。
内容的提问来源于stack exchange,提问作者Jack Finnegan
相关产品推荐
相关产品推荐

