ggplot2设置datetime轴时间限值后所有数据点消失问题
问题原因
自定义轴限值的生成逻辑存在两个错误,直接导致所有数据落在轴范围外被过滤:
- 用
strptime解析"35:00"/"25:00"时仅指定了分、秒格式,没有传入年、月、日信息,R会默认给这两个时间补上当前系统日期作为日期部分,最终生成的POSIXct时间是「当前系统日期 00:35:00 CET」和「当前系统日期 00:25:00 CET」,和数据集里2022-06-08的时间点完全不在同一时间区间,没有任何重叠。 - 传入
limits的参数顺序错误:ggplot坐标轴的limits要求输入顺序为c(轴最小值, 轴最大值),原代码先写35分、后写25分,即使日期匹配,轴范围也是反向的无效区间。
可行解决方案
根据你的绘图需求二选一即可:
方案1:保留完整日期时间轴,限定当前数据的显示范围
生成限值时补全和数据集一致的日期信息,不要只传分秒,同时调整限值顺序为小值在前、大值在后:
library(ggplot2) # 生成和数据同日期的轴上下限 lims <- as.POSIXct( c("2022-06-08 00:25:00", "2022-06-08 00:35:00"), tz = "CET" ) ggplot(df_test, aes(x = ID, y = timing)) + geom_point(size = 2) + scale_y_datetime(limits = lims)
运行后即可正常显示两个数据点,y轴范围固定在你设定的00:25到00:35区间。
方案2:仅对比时分秒维度,不显示完整日期
如果你的数据可能来自不同日期,只需要按一天内的时刻(分秒维度)展示,不要直接用原始POSIXct值做轴映射,先把时间转换为当日0点起的累计秒数剥离年月日信息,再将轴标签格式化回分秒样式即可:
library(ggplot2) # 将时间转换为当日0点起的累计秒数,移除年月日属性 df_test$time_sec <- as.numeric(format(df_test$timing, "%H"))*3600 + as.numeric(format(df_test$timing, "%M"))*60 + as.numeric(format(df_test$timing, "%S")) # 对应25分=1500秒,35分=2100秒作为轴范围 lims_sec <- c(25*60, 35*60) ggplot(df_test, aes(x = ID, y = time_sec)) + geom_point(size = 2) + scale_y_continuous( limits = lims_sec, # 将秒数标签转回分:秒格式 labels = function(x) sprintf("%02d:%02d", floor(x/60), round(x %% 60)), name = "timing" )
这种写法不受数据日期差异影响,适合跨日期对比相同时刻的场景。
内容的提问来源于stack exchange,提问作者user1345332
相关产品推荐
相关产品推荐

