ggplot日期格式识别异常:含毫秒的POSIXct时间轴显示混乱
问题:ggplot x轴时间显示混乱(含毫秒的POSIXct数据)
我用以下代码绘制图表:
p1 <- ggplot(data = mydat, aes(x = time))+ geom_line(aes(y = sumabsdiff, colour = 'sumabsdiff'))+ geom_line(aes(y = windsize, col='windsize'))+ scale_x_time(breaks = scales::date_breaks('1 sec'))+ #('15 secs'))+ scale_color_manual(values=c('sumabsdiff' = 'black', "windsize" = "red"))+ theme(legend.position = "top")
图表的x轴日期显示混乱,但time字段打印出来看起来正常:
> mydat$time [1] "2022-09-19 12:44:47 UTC" "2022-09-19 12:44:48 UTC" "2022-09-19 12:44:49 UTC" "2022-09-19 12:44:50 UTC" [5] "2022-09-19 12:44:50 UTC" "2022-09-19 12:44:50 UTC".
数据结构显示time是带毫秒的POSIXct类型:
mydf <- structure(list(time = structure(c(1663591487.801, 1663591488.614, 1663591489.626, 1663591490.097, 1663591490.202, 1663591490.717 ), class = c("POSIXct", "POSIXt"), tzone = "UTC"), bid = c(11735.68, 11735.18, 11734.93, 11734.43, 11734.3, 11734.43), ask = c(11737.58, 11737.08, 11736.83, 11736.33, 11736.2, 11736.33), flags = c(6, 6, 6, 6, 6, 6), typical = c(11736.63, 11736.13, 11735.88, 11735.38, 11735.25, 11735.38), row = 266:271, prevrow_short = c(258L, 258L, 260L, 261L, 262L, 265L), windsize = c(9, 10, 9, 9, 9, 7), diff = c(-0.119999999998981, -0.5, -0.25, -0.5, -0.130000000001019, 0.130000000001019), absdiff = c(0.119999999998981, 0.5, 0.25, 0.5, 0.130000000001019, 0.130000000001019), sumabsdiff = c(3.60999999999694, 4.10999999999694, 3.72999999999593, 3.85999999999694, 3.61999999999898, 2.13000000000102), positive = c(FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), meanpos = c(0.444444444444444, 0.4, 0.333333333333333, 0.222222222222222, 0.222222222222222, 0.285714285714286), posdiff = c(0, 0, 0, 0, 0, 0.130000000001019), negdiff = c(0.119999999998981, 0.5, 0.25, 0.5, 0.130000000001019, 0), sumposdiff_short = c(1.36999999999898, 1.36999999999898, 1.23999999999796, 0.869999999998981, 0.869999999998981, 0.630000000001019), sumnegdiff_short = c(2.23999999999796, 2.73999999999796, 2.48999999999796, 2.98999999999796, 2.75, 1.5), power_short = c(0.37950138504159, 0.333333333333333, 0.332439678283999, 0.225388601036184, 0.240331491712493, 0.295774647887661), market_open = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), timediff = c(0.219000101089478, 0.812999963760376, 1.01199984550476, 0.470999956130981, 0.105000019073486, 0.515000104904175 ), avgspeed = c(2.71247733209185, 2.42072135038066, 2.44698207323042, 2.3255814641193, 2.8019926211971, 2.14658085742225), relative_positive_diff = c(0.37950138504159, 0.333333333333333, 0.332439678283999, 0.225388601036184, 0.240331491712493, 0.295774647887661), timesec = structure(c(1663591487, 1663591488, 1663591489, 1663591490, 1663591490, 1663591490), class = c("POSIXct", "POSIXt"), tzone = "UTC")), pandas.index = <environment>, row.names = 266:271, class = "data.frame")
推测是time字段包含毫秒导致x轴显示混乱,该如何解决?
解决方案
方法1:将时间向下取整到秒级
直接把time字段取整到秒,消除毫秒差异,让刻度对齐更清晰:
# 加载lubridate包处理时间 library(lubridate) # 新增取整后的秒级时间列 mydat$time_sec <- floor_date(mydat$time, unit = "second") # 使用新列绘图 p1 <- ggplot(data = mydat, aes(x = time_sec))+ geom_line(aes(y = sumabsdiff, colour = 'sumabsdiff'))+ geom_line(aes(y = windsize, col='windsize'))+ scale_x_datetime(breaks = scales::date_breaks('1 sec'), labels = scales::date_format("%H:%M:%S"))+ scale_color_manual(values=c('sumabsdiff' = 'black', "windsize" = "red"))+ theme(legend.position = "top")
注意:将scale_x_time替换为scale_x_datetime,更适配POSIXct类型的时间数据。
方法2:自定义刻度标签,忽略毫秒
不修改原始数据,直接让刻度对齐到整秒,标签只显示时分秒:
library(lubridate) p1 <- ggplot(data = mydat, aes(x = time))+ geom_line(aes(y = sumabsdiff, colour = 'sumabsdiff'))+ geom_line(aes(y = windsize, col='windsize'))+ scale_x_datetime( breaks = function(x) floor_date(x, unit = "second"), labels = scales::date_format("%H:%M:%S") )+ scale_color_manual(values=c('sumabsdiff' = 'black', "windsize" = "red"))+ theme(legend.position = "top")
方法3:保留毫秒显示(需调整布局)
如果必须展示毫秒,可调整刻度间隔和标签角度避免重叠:
p1 <- ggplot(data = mydat, aes(x = time))+ geom_line(aes(y = sumabsdiff, colour = 'sumabsdiff'))+ geom_line(aes(y = windsize, col='windsize'))+ scale_x_datetime( breaks = scales::date_breaks('0.5 sec'), # 根据数据密度调整间隔 labels = scales::date_format("%H:%M:%OS3") # 显示三位毫秒 )+ scale_color_manual(values=c('sumabsdiff' = 'black', "windsize" = "red"))+ theme( legend.position = "top", axis.text.x = element_text(angle = 45, hjust = 1) # 旋转标签防止重叠 )
内容的提问来源于stack exchange,提问作者gaut
相关产品推荐
相关产品推荐

