如何创建基于时间区间的可变宽度Bar Chart/Histogram
实现基于时间跨度的条形图(Bar Chart)
嘿,这个需求其实完全可以实现,本质上是做一个基于时间跨度的条形图——每个条形的宽度对应s1(开始时间)到s2(结束时间)的时长,高度绑定第三列数据,X轴固定为0-24小时的时间轴。我用Python的matplotlib给你演示具体怎么做,思路也适用于Excel、Tableau这类工具:
核心思路
- 把时间字符串转换成小时数值(比如12:00 AM=0,1:45 AM=1.75),方便计算时间段的宽度和定位条形位置
- 用每个时间段的开始小时数作为条形的起始位置,结束时间-开始时间作为条形宽度
- 条形高度直接用第三列的数值即可
代码示例(Python + Matplotlib)
首先处理数据,再绘图:
import matplotlib.pyplot as plt import pandas as pd # 模拟你的数据结构 sample_data = { 's1': ['12:00 AM', '2:00 AM', '8:30 AM', '1:15 PM', '6:45 PM'], 's2': ['1:45 AM', '2:30 AM', '10:15 AM', '3:45 PM', '8:00 PM'], 'height': [5, 3, 7, 4, 6] } df = pd.DataFrame(sample_data) # 辅助函数:把12小时制时间转成0-24的小时数值 def convert_to_hours(time_str): period = time_str.split()[-1] hh, mm = map(int, time_str.split()[0].split(':')) # 处理AM/PM转换 if period == 'PM' and hh != 12: hh += 12 elif period == 'AM' and hh == 12: hh = 0 # 转换成带分钟的小时数(比如1:45 AM = 1.75) return hh + mm / 60 # 计算每个时间段的起始小时和持续时长 df['start_hour'] = df['s1'].apply(convert_to_hours) df['duration'] = df['s2'].apply(convert_to_hours) - df['start_hour'] # 绘制条形图 plt.figure(figsize=(12, 6)) # 关键参数:align='edge'让条形从start_hour位置开始,而不是居中 plt.bar( x=df['start_hour'], height=df['height'], width=df['duration'], align='edge', edgecolor='black', alpha=0.7 ) # 美化X轴:显示0-24小时的时间格式 plt.xticks( ticks=range(0, 25), labels=[ "12:00 AM" if h == 0 else f"{h}:00 AM" if h <12 else "12:00 PM" if h ==12 else f"{h-12}:00 PM" for h in range(0,25) ], rotation=45 ) plt.xlabel('Time of Day') plt.ylabel('Value') plt.title('Time-Span Bar Chart') plt.xlim(0, 24) # 锁定X轴在0-24小时区间 plt.tight_layout() plt.show()
注意事项
- 如果遇到跨午夜的时间段(比如s1=11:00 PM,s2=1:00 AM),直接绘图会出现反向条形(因为结束小时数<开始小时数),这时候需要把该时间段拆成两行:
23:00-24:00和0:00-1:00,分别绘制两个条形 - 其他工具(比如Excel)的思路类似:先把时间转成数值格式(Excel里时间本身就是0-1的数值,乘以24就是小时数),然后设置条形图的「分类间距」为0,用开始时间作为X值,时长作为条形宽度
内容的提问来源于stack exchange,提问作者PVic
相关产品推荐
相关产品推荐

