如何用ggplot2绘制跨天24小时时钟的散点图?
解决无日期24小时时间散点图的Y轴冗余标签问题
问题说明
使用tidyverse v1.3.2生成数据的代码如下:
submits <- tibble::tribble( ~ id, ~ submission, ~ day, 1, "18:25:12", 2, 2, "01:37:40", 3, 3, "11:40:50", 2, 4, "00:55:00", 2 )
生成的数据集:
# A tibble: 4 × 3 id submission day <dbl> <chr> <dbl> 1 1 18:25:12 2 2 2 01:37:40 3 3 3 11:40:50 2 4 4 00:55:00 2
其中submission列是无日期的24小时制提交时间,day列代表参考日期到提交日期的间隔天数。尝试绘制以day为横轴、submission为纵轴的散点图时,使用以下代码会导致Y轴出现冗余的00:00标签,显示效果不佳:
submits %>% mutate(submission = as.POSIXct(submission, format = "%H:%M:%S")) %>% ggplot(aes(x= day, y = submission)) + geom_point() + scale_y_datetime( date_labels = "%H:%M", limits = c(as.POSIXct("00:00:01", format="%H:%M:%S"), as.POSIXct("23:59:59", format="%H:%M:%S")))
可行解决方案
方法1:使用hms包处理时间类型
hms包专门用于存储无日期的时间数据,ggplot对该类型的支持更适配,不会引入日期相关的冗余刻度:
library(tidyverse) library(hms) submits %>% mutate(submission = as_hms(submission)) %>% ggplot(aes(x = day, y = submission)) + geom_point(size = 3) + labs(x = "间隔天数", y = "提交时间") + theme_minimal()
运行后Y轴会自动生成合理的24小时制时间刻度,无冗余标签。
方法2:转换为小数小时并自定义刻度
将时间转换为一天中的小数小时数值,再手动设置Y轴的刻度标签为24小时格式:
submits %>% mutate( submission = hms::as_hms(submission), hour_decimal = as.numeric(submission) / 3600 # 转换为小时单位的小数 ) %>% ggplot(aes(x = day, y = hour_decimal)) + geom_point(size = 3) + scale_y_continuous( breaks = seq(0, 24, 3), # 每3小时一个刻度 labels = function(x) sprintf("%02d:00", as.integer(x)) ) + labs(x = "间隔天数", y = "提交时间") + theme_minimal()
这种方式可以灵活调整刻度间隔和标签样式。
方法3:统一POSIXct的基准日期
如果坚持使用POSIXct类型,需给所有时间指定同一个基准日期,避免因日期差异导致的刻度异常:
base_date <- as.POSIXct("2020-01-01") # 任意固定基准日期 submits %>% mutate( submission = base_date + hms::as_hms(submission) ) %>% ggplot(aes(x = day, y = submission)) + geom_point(size = 3) + scale_y_datetime( date_labels = "%H:%M", breaks = seq(base_date, base_date + 24*3600, 3*3600), limits = c(base_date, base_date + 24*3600 - 1) ) + labs(x = "间隔天数", y = "提交时间") + theme_minimal()
通过固定基准日期,所有时间都落在同一天内,Y轴只会显示当天的24小时刻度,不会出现冗余标签。
内容的提问来源于stack exchange,提问作者medium-dimensional
相关产品推荐
相关产品推荐

