如何用Python(Bokeh)基于CSV数据绘制按小时统计的速度折线图
解决按一天小时统计平均速度并绘制折线图的问题
你的核心需求是聚合不同日期同一小时的速度数据,分析一天中各时段的平均速度,原代码的问题在于:
- 将
Time转为dt.time对象后,Bokeh的datetime轴无法正确识别这类非完整datetime类型的数据 - 按完整的时分分组,而非按小时聚合,导致数据分散在具体时间点,无法体现时段趋势
下面给出两种可行的修改方案:
方案一:使用datetime轴显示24小时刻度
这种方案保留Bokeh的datetime轴特性,通过虚拟日期构造可识别的时间格式:
import pandas as pd from bokeh.plotting import figure, output_file, show from bokeh.models import ColumnDataSource, HoverTool output_file('Speed.html') file = 'C:/Users/oof/Desktop/route.csv' df = pd.read_csv(file) # 完整解析时间为datetime类型,保留日期和时间信息 df['Time'] = pd.to_datetime(df['Time'], format='%m/%d/%Y %H:%M') # 提取小时字段,用于按小时分组 df['Hour'] = df['Time'].dt.hour # 按小时分组计算平均速度,重置索引让Hour成为列 grouped_by_hour = df.groupby('Hour')[['Speed']].mean().reset_index() # 构造Bokeh可识别的datetime格式:用虚拟日期+当前小时,确保x轴显示为一天的时间 grouped_by_hour['DisplayTime'] = pd.to_datetime(grouped_by_hour['Hour'], format='%H') source = ColumnDataSource(grouped_by_hour) # 创建图表,指定x轴为datetime类型 p1 = figure( x_axis_type='datetime', title='Average Speed in a Day', y_axis_label='Average Speed', x_axis_label='24-Hour' ) p1.line(x='DisplayTime', y='Speed', line_width=2, source=source) # 配置hover提示,显示小时和对应平均速度 TOOLTIP1 = [ ("Hour", "@Hour:00"), ("Average Speed", "@Speed") ] p1.add_tools(HoverTool(tooltips=TOOLTIP1, mode='vline')) show(p1)
方案二:使用线性轴直接显示0-23小时
如果不需要datetime轴的时间格式,直接用线性轴显示小时数更简洁:
import pandas as pd from bokeh.plotting import figure, output_file, show from bokeh.models import ColumnDataSource, HoverTool output_file('Speed.html') file = 'C:/Users/oof/Desktop/route.csv' df = pd.read_csv(file) # 解析时间并提取小时 df['Time'] = pd.to_datetime(df['Time'], format='%m/%d/%Y %H:%M') df['Hour'] = df['Time'].dt.hour # 按小时聚合平均速度 grouped_by_hour = df.groupby('Hour')[['Speed']].mean().reset_index() source = ColumnDataSource(grouped_by_hour) # 创建线性轴图表,限定x轴范围0-23 p1 = figure( x_range=(0, 23), title='Average Speed in a Day', y_axis_label='Average Speed', x_axis_label='24-Hour' ) p1.line(x='Hour', y='Speed', line_width=2, source=source) # 配置hover提示 TOOLTIP1 = [ ("Hour", "@Hour:00"), ("Average Speed", "@Speed") ] p1.add_tools(HoverTool(tooltips=TOOLTIP1, mode='vline')) show(p1)
关键改动说明
- 数据聚合逻辑:从按具体时分分组改为按
dt.hour分组,确保不同日期同一小时的数据被合并计算平均速度 - 轴类型适配:要么构造Bokeh可识别的datetime格式,要么直接用小时数作为线性轴数据,避免原代码中
dt.time对象导致的轴显示问题 - 交互优化:hover提示直接显示小时区间,更贴合时段分析的需求
内容的提问来源于stack exchange,提问作者WJstudent
相关产品推荐
相关产品推荐

