R ggplot2 geom_rect堆积起来

时间:2013-11-09 07:59:55

标签: r ggplot2

我想在时间尺度上叠加一个情节。以下是我的数据:

 Flight_No Dest      Date  Time STD.60 STD.45      Date2          start       end
1    ab0729  KP 14-Oct-13 00:05      1      0 2013-10-14 2013-10-14 00:05:00 2013-10-14 00:20:00
2    ab8063  KI 14-Oct-13 00:20      0      3 2013-10-14 2013-10-14 00:20:00 2013-10-14 00:35:00
3    ab0337  ST 14-Oct-13 00:30      1      0 2013-10-14 2013-10-14 00:30:00 2013-10-14 00:45:00

下面是我绘制图表的代码:

data$Total<-data$STD.60+data$STD.45    
ggplot(data,aes(x=start,y=Total,xmin=start,xmax=end,ymin=0,ymax=Total,alpha=0,fill=factor(Dest)))+geom_rect()

上面生成此图表:

enter image description here

但是,我想在有重叠的情况下堆叠这些矩形。即在00:30到00:35之间,y轴值应显示为4而不是3。

请帮忙。

2 个答案:

答案 0 :(得分:3)

日期排序后,很容易计算重叠范围。 对于每个间隔,我检查是否有任何重叠(开始&gt;结束),如果是,我将下一个总计添加到当前一个。

## choose just relevant columns
d <- dat[,c('start','end','Dest','Total')]
# Make sure the data is sorted
d <- d[ order(d$start), ]
h <- d
## here all the main stuff
for (i in head(seq_len(nrow(d)),-1)){
  if(d[i+1,'start'] < d[i,'end']){
    xx <- d[i,]
    xx$start <- d[i+1,'start'] 
    xx$Total <- d[i,'Total'] +d[i+1,'Total']
    h <- rbind(h,xx)   
  }
}

library(ggplot2)
ggplot(h,aes(x=start,y=Total,xmin=start,xmax=end,ymin=0,ymax=Total,
             ,fill=factor(Dest),alpha=0))+
  geom_rect()

编辑

我使用scale_x_datetime添加手动x轴标签。我还使用scales包格式化日期。

library(scales)
last_plot()
scale_x_datetime(breaks=unique(c(h$start,h$end)),
               labels = date_format("%H:%M"))

enter image description here

答案 1 :(得分:2)

这是一个依赖于以下方面的解决方案:(1)将时间轴拆分为5分钟宽的区间,(2)以长格式重建数据,以及(3)利用{{1}的堆叠能力}。

enter image description here

geom_bar(position="stack")

注意:

  1. 您可以通过更改dat = structure(list(Dest = c("KP", "KI", "ST"), Total = c(1L, 3L, 1L), start = structure(c(1381730700, 1381731600, 1381732200), class = c("POSIXct", "POSIXt"), tzone = ""), end = structure(c(1381731600, 1381732500, 1381733100), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = c("Dest", "Total", "start", "end"), class = "data.frame", row.names = c(NA, -3L)) # Use loop to split each row of data into bins. Time = as.POSIXct(vector()) Dest = vector("character", length=0) Total = vector("integer", length=0) for (i in seq(nrow(dat))) { times = seq(from=dat[i, "start"], to=dat[i, "end"], by="5 min") times = head(times, -1) # Remove last element. Time = c(Time, times) Dest = c(Dest, rep(dat[i, "Dest"], length(times))) Total= c(Total, rep(dat[i, "Total"], length(times))) } dat2 = data.frame(Time, Total, Dest) library(ggplot2) p = ggplot(dat2, aes(x=Time, y=Total, fill=Dest)) + geom_bar(stat="identity", position="stack", width=300, color="grey30") ggsave("plot.png", plot=p, width=10, height=4.5, dpi=120) 参数来更改bin宽度。请参阅seq(..., by=
  2. 您可能需要将?seq.POSIXtstart时间舍入到最接近的x分钟,以简化分箱过程。
  3. end有效,因为5分钟内有300秒。根据需要进行调整。
  4. x轴上的刻度线位于条形的中心,但它们确实应用了条形的左边缘。如@agstudy所示,使用geom_bar(..., width=300)进行调整。