如何让geom_segment在跨天班次可视化时分段显示
解决班次重叠可视化的跨天分段问题
步骤1:预处理数据,拆分跨天班次
首先需要将跨天的班次拆分为两段:当天结束到23:59,以及次日00:00到结束时间。通过生成嵌套时间段列表再展开的方式自动处理:
library(lubridate) library(tibble) library(dplyr) library(tidyr) library(ggplot2) # 原始班次数据 shift_info <- tibble( shift = c("Shift 1", "Shift 2", "Shift 3"), start_time = ymd_hms(c("2023-03-03 08:00:00", "2023-03-03 08:00:00", "2023-03-03 16:00:00")), end_time = ymd_hms(c("2023-03-03 20:00:00", "2023-03-03 16:00:00", "2023-03-04 04:00:00")) ) # 拆分跨天班次 shift_processed <- shift_info %>% mutate( # 生成时间段列表:跨天则拆成两段,否则保留原时间段 time_segments = pmap(list(start_time, end_time), function(start, end) { if (date(start) == date(end)) { tibble(start = start, end = end) } else { tibble( start = c(start, floor_date(end, "day")), end = c(ceiling_date(start, "day") - seconds(1), end) ) } }) ) %>% unnest(time_segments) %>% # 将时间转换为一天中的小时数(便于X轴映射) mutate( start_hour = hour(start) + minute(start)/60 + second(start)/3600, end_hour = hour(end) + minute(end)/60 + second(end)/3600 )
步骤2:用geom_segment绘制可视化图
处理后的数据可直接用于绘图,跨天班次会自动分成两段显示:
ggplot(shift_processed, aes(y = shift)) + # 绘制班次线段 geom_segment(aes(x = start_hour, xend = end_hour, yend = shift), size = 3, color = "#2E86AB") + # 设置X轴为一天的小时,格式化显示 scale_x_continuous( breaks = seq(0, 23, 4), labels = sprintf("%02d:00", seq(0, 23, 4)), limits = c(0, 23.999) ) + # 添加轴标签和标题 labs( x = "一天中的时间", y = "班次", title = "班次时间重叠可视化" ) + theme_minimal() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.title = element_text(size = 12) )
关键说明
- 数据处理部分通过
pmap和unnest自动识别跨天班次并拆分,无需手动逐个处理 - 将时间转换为小时数后,X轴可直接映射为连续时间轴,完美覆盖00:00到23:59的范围
geom_segment会根据拆分后的每行数据绘制线段,跨天班次自然分成两段显示
内容的提问来源于stack exchange,提问作者mikeytop
相关产品推荐
相关产品推荐

