【问题标题】:Plot dates on the x axis and time on the y axis with ggplot2使用 ggplot2 在 x 轴上绘制日期,在 y 轴上绘制时间
【发布时间】:2011-11-19 06:26:18
【问题描述】:

我已经阅读了一系列 37 个日期和时间的事件发生。它现在作为 POSIXlt 对象存在。我想要每天事件发生的时间的图形表示。所以 x 轴应该是日期,y 轴应该是一天中的时间。

然后我尝试用 ggplot2 绘制它

qplot(day(dttm), hour(dttm))

这正是我想要的,但它没有分钟的分辨率。如何在 y 轴中包含小时和分钟?

这是一些示例数据

dttm
 [1] "2011-11-16 10:39:20" "2011-11-16 10:56:32" "2011-11-16 11:52:43" "2011-11-16 12:10:42"
 [5] "2011-11-16 13:10:13" "2011-11-16 13:41:10" "2011-11-16 13:48:07" "2011-11-16 14:54:04"
 [9] "2011-11-17 07:05:23" "2011-11-17 07:34:24" "2011-11-17 07:53:01" "2011-11-17 07:57:04"
[13] "2011-11-17 08:09:16" "2011-11-17 08:23:43" "2011-11-17 10:20:54" "2011-11-17 10:45:13"
[17] "2011-11-17 10:49:32" "2011-11-17 11:16:08" "2011-11-17 11:24:05" "2011-11-17 11:50:11"
[21] "2011-11-17 11:52:47" "2011-11-17 11:54:42" "2011-11-17 11:55:25" "2011-11-17 11:57:34"
[25] "2011-11-17 12:06:15" "2011-11-17 12:08:05" "2011-11-17 12:08:33" "2011-11-17 12:30:13"
[29] "2011-11-17 13:24:41" "2011-11-17 13:44:41" "2011-11-17 13:48:55" "2011-11-17 14:59:08"
[33] "2011-11-18 06:46:17" "2011-11-18 07:52:50" "2011-11-18 08:31:22" "2011-11-18 08:33:43"
[37] "2011-11-18 08:50:08"

这是 dput 文件

structure(list(sec = c(20, 32, 43, 42, 13, 10, 7, 4, 23, 24, 
1, 4, 16, 43, 54, 13, 32, 8, 5, 11, 47, 42, 25, 34, 15, 5, 33, 
13, 41, 41, 55, 8, 17, 50, 22, 43, 8), min = c(39L, 56L, 52L, 
10L, 10L, 41L, 48L, 54L, 5L, 34L, 53L, 57L, 9L, 23L, 20L, 45L, 
49L, 16L, 24L, 50L, 52L, 54L, 55L, 57L, 6L, 8L, 8L, 30L, 24L, 
44L, 48L, 59L, 46L, 52L, 31L, 33L, 50L), hour = c(10L, 10L, 11L, 
12L, 13L, 13L, 13L, 14L, 7L, 7L, 7L, 7L, 8L, 8L, 10L, 10L, 10L, 
11L, 11L, 11L, 11L, 11L, 11L, 11L, 12L, 12L, 12L, 12L, 13L, 13L, 
13L, 14L, 6L, 7L, 8L, 8L, 8L), mday = c(16L, 16L, 16L, 16L, 16L, 
16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 
17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 
17L, 18L, 18L, 18L, 18L, 18L), mon = c(10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 10L, 10L, 10L), year = c(111L, 111L, 111L, 111L, 
111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 
111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 
111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L, 111L
), wday = c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L), yday = c(319L, 319L, 319L, 319L, 
319L, 319L, 319L, 319L, 320L, 320L, 320L, 320L, 320L, 320L, 320L, 
320L, 320L, 320L, 320L, 320L, 320L, 320L, 320L, 320L, 320L, 320L, 
320L, 320L, 320L, 320L, 320L, 320L, 321L, 321L, 321L, 321L, 321L
), isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("sec", "min", 
"hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", 
"POSIXt"))

【问题讨论】:

    标签: r datetime ggplot2 lubridate


    【解决方案1】:

    需要两个步骤:

    • 从 POSIXct 对象中提取时间元素。您可以使用一些lubridate 提取器函数和一些算术,或者通过从dttm 中减去as.Date(dttm) 来做到这一点。我展示了两种方式。
    • 添加日期时间 y 轴并指定合适的格式化程序

    从 POSIXct 对象中提取时间的两种替代方法:

    dropDate <- function(x){
      3600*hour(x)+60*minute(x)+second(x)
    }
    
    dropDate2 <- function(x){
      as.numeric(x - as.Date(x))
    }  
    

    您可能还希望为轴指定显式标签:

    qplot(day(dttm), dropDate(dttm)) + 
        scale_y_datetime(format="%H:%M:%S") + 
        xlab("Day") + ylab("Hour")
    


    ?scale_datetime 中有更多此类比例的示例,它将指向?strptime 以获取有关日期和时间格式代码的说明。

    【讨论】:

    • 唉,hour(dttm)*3600 不提供分秒的分辨率。它在四舍五入到最接近的整点钟的所有时间上都出现了过度绘制。
    • @Farrel 好的,我以为你只想修改比例。答案已编辑。
    【解决方案2】:

    您可以使用 scale_datetime 调整日期轴。最后的例子很能说明问题。

    http://had.co.nz/ggplot2/scale_datetime.html

    【讨论】: