【问题标题】:Time series visualization for start, end, duration in RR中开始,结束,持续时间的时间序列可视化
【发布时间】:2012-05-05 19:30:39
【问题描述】:

我有以下数据:

> Data
          Date    Start       End
1   2011-11-15 12:01:27 12:30:15 
2   2011-11-16 12:01:25 12:32:15 
3   2011-11-17 12:01:02 12:39:12 
4   2011-11-19 12:01:12 12:30:18

我还附加了一个持续时间列

Data[,4] <- as.numeric(difftime(Data$End,Data$Start))
names(Data)[4] <- "Duration"

我的脑海中有一个 Start,End 的可视化,看起来有点像股票 candlestickOHLC 图表,其中 x 值是日期,y 是 End - Start。

结束在顶部,矩形下降到开始——矩形的高度随着时间的推移而变化。也就是说,每个 Date 都有不同的矩形高度,由 Start 和 End 之间的差异决定。

这里的 x 轴从 2011-11-15 到 2011-11-19。 y 轴从 12:00:00 到 12:40:00。

是否有任何 ggplot 向导看到了一种简单的方法来做到这一点?由于 Start 和 End 都随着时间而变化,我是否必须使用 geom_ribbon 或 geom_polygon 而不是 geom_bar 或 geom_area?

如果在 Duration 的值大于 2 个标准差的日子里,条形的颜色可以变为红色,那就更酷了!

【问题讨论】:

    标签: r ggplot2 data-visualization time-series candlestick-chart


    【解决方案1】:

    我使用与 nico 类似的结构(谢谢!):

    date = c("2011-11-15", "2011-11-16", "2011-11-17", "2011-11-19")
    start = c("12:01:27", "12:01:25", "12:01:02", "12:01:12")
    end = c("12:30:15", "12:32:15", "12:39:12", "12:30:18")
    

    接下来,我们将其放入包含矩形角的数据框中:

    ##I've made the rectangles 2 hours wide
    df = data.frame(date = as.POSIXct(date),
             ystart = as.POSIXct(start, format="%H:%M:%S"), 
             yend = as.POSIXct(end, format="%H:%M:%S"),
             xstart=as.POSIXct(paste(date, "12:00:00"), format="%Y-%m-%d %H:%M:%S"),
             xend = as.POSIXct(paste(date, "14:00:00"), format="%Y-%m-%d %H:%M:%S"))
    

    那我们就用geom_rect:

    ggplot() + geom_rect(data=df, aes(ymin=ystart, ymax=yend,
                               xmin=xend, xmax=xstart))
    

    如果您想根据条件将其中一些设为红色,只需在您的数据框上创建一个额外的列:

    ##Your condition is something to do with the sd
    df$isRed = c(TRUE, FALSE)
    

    然后添加两个ggplot层:

    ggplot() + geom_rect(data=subset(df, !isRed), aes(ymin=ystart, ymax=yend,
                               xmin=xend, xmax=xstart)) +
               geom_rect(data=subset(df, isRed), aes(ymin=ystart, ymax=yend,
                               xmin=xend, xmax=xstart), colour="red")
    

    示例图表

    【讨论】:

    • 这是否更容易还有待商榷,但您可以将colour 参数指定为美学并手动调整比例,如下所示:ggplot(df, aes(date, ymin = y.from, ymax = y.to, colour = isRed)) + geom_linerange() + scale_colour_manual(values = c("TRUE" = "red", "FALSE" = "black"), guide = "none")。使用两种颜色,添加单独的几何图形可以说同样容易,但可能没有那么可扩展。
    • 很抱歉让您感到困惑。 Nico 得到了我在美学上寻找的东西。这很接近,我喜欢 ggplot,但 geom_linerange 可以产生比线条更宽的条吗?
    【解决方案2】:

    我不使用 ggplot,但我可以给你一个基本的 R 解决方案

    # Generate the data
    date <- c("2011-11-15", "2011-11-16", "2011-11-17", "2011-11-19")
    start <- c("12:01:27", "12:01:25", "12:01:02", "12:01:12")
    end <- c("12:30:15", "12:32:15", "12:39:12", "12:30:18")
    
    # Put everything in a data frame and convert to POSIXct objects
    # The times will be all converted to today's date
    # but this will not influence the plot
    df <- data.frame(date = as.POSIXct(date),
                     start = as.POSIXct(start, format="%H:%M:%S"), 
                     end = as.POSIXct(end, format="%H:%M:%S"))
    
    # Get the working range for the axes in order to make them nicer (see below)
    x.from <- as.POSIXct(min(date))
    x.to <- as.POSIXct(max(date))
    y.from <- as.POSIXct(min(start), format="%H:%M:%S")
    y.to <- as.POSIXct(max(end), format="%H:%M:%S")
    
    # Create an empty plot, as rect will not create a new one
    # We put no axes on the plot
    plot(0, "n", xaxt="n", yaxt="n", ylab="", xlab="Day", 
         ylim=c(from, to), xlim=range(df$date))
    
    # Now draw the rectangles (I made them 2 hours-wide)
    rect(df$date-3600, df$start, df$date+3600, df$end, col="black")
    
    days <- seq(x.from, x.to, 24*3600)
    times <- seq(y.from, y.to, 300) # 5 min (=300 s) axis ticks
    # Finally add the axes
    axis(1, at=days, labels=strftime(days, "%d/%m"))
    axis(2, at=times, labels=strftime(times, "%H:%M"), las=1)
    

    结果:

    【讨论】:

    • 对不起,现在没时间添加颜色位,今晚会尝试添加它(除非出现其他更优雅的解决方案)
    • 这非常接近。我正在寻找更宽的条形图(几乎可以触及),但是一旦我添加了我拥有的 2 年左右的数据点,这肯定会是一个有趣的图表。感谢您的指导!
    • @Mittenchops:只需在 rect 调用中将 3600 更改为更高的值,以获得更宽的条形;)
    • 你太棒了,@nico,谢谢。我需要更好地理解这里的机制(以及我将如何改变它以处理多年来扩展的时间序列,并改变极端的颜色),但这帮助我制作了一个很棒的图表。谢谢!
    • @Mittenchops:R“思考”以秒为单位,因此 x 轴上的每个刻度为 1 天,如果您的条形图为 7200 秒宽,则意味着它们将覆盖 2 小时,因此 1/12 的空间在 2 个刻度之间。
    猜你喜欢
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2013-10-24
    • 1970-01-01
    • 2015-03-13
    相关资源
    最近更新 更多