Klaus
Klaus

Reputation: 2056

Stacked curves in geom_area plot

How to stack the graphs in the following example?

a<-as.POSIXlt("2013-07-01 00:00:00",origin = "1960-01-01",tz="GMT")
b<-as.POSIXlt("2013-07-08 00:00:00",origin = "1960-01-01",tz="GMT")
woche1<-sample(seq(as.numeric(a),by=60*60,length.out=200),200,T)
woche2<-sample(seq(as.numeric(b),by=60*60,length.out=200),200,T)
times<-c(woche1,woche2)
class(times)<-c("POSIXt","POSIXct") 
times<-as.POSIXlt(times,origin = "1960-01-01",tz="GMT")
key<-sample(LETTERS[1:3],200,T)
df<-data.frame(times=times,order=factor(rep(1:2,each=100)), key=key)
p<-ggplot(df, aes(x=times))
p<-p + geom_area(aes(y = ..count.., fill = key, group = key),stat = "bin",position = 'stack')#,position = 'stack'
p<-p + facet_wrap( ~ order,scales="free_x")
p

Upvotes: 1

Views: 1572

Answers (2)

Didzis Elferts
Didzis Elferts

Reputation: 98429

As already mentioned in the question you linked in comment, problem is that in your data times are different for each key and so they can't be stacked.

To solve the problem you have to make time sequence that will be equal for all key values. For example made tim.seq that consist of 12 hour time segments

tim.seq<-seq(as.POSIXlt("2013-07-01 00:00:00",origin = "1960-01-01",tz="GMT"),
             as.POSIXlt("2013-07-16 12:00:00",origin = "1960-01-01",tz="GMT"),by="12 hours")

Now using function cut() add new column times2 to existing data frame to show to which time segment each observation belongs.

df$times2<-cut(df$times,breaks=tim.seq)

Then using function ddply() from library plyr aggregate your data to have number of occurrence of each time step. Add times2 should be made as POSIXct class for plotting.

df2<-ddply(df,.(order,times2,key),nrow)
df2$times2<-as.POSIXct(df2$times2)

To this data frame you should add also missing time periods to get pretty look (0 values). This can be done by making all possible combination of order, times2 and key and then merging with data frame df2. This will make NA values in V1 for missing times, they are replaced with 0.

df3<-expand.grid(unique(df2$order),unique(df2$times2),unique(df2$key))
colnames(df3)<-c("order","times2","key")
df4<-merge(df2,df3,by=c("times2","order","key"),all=TRUE)
df4$V1[is.na(df4$V1)]<-0

Now you can get stacked area plot.

ggplot(df4,aes(x=times2,y=V1,fill=key))+geom_area(stat="identity")+
  facet_wrap( ~ order,scales="free_x")

enter image description here

Upvotes: 3

Edwin
Edwin

Reputation: 3242

Indeed a bit unclear, but I think you want the graphs to be on top of each other instead of next to each other. To do this just add nrow = 2 to the facet_wrap

p<-p + facet_wrap( ~ order,scales="free_x", nrow = 2)

If this is not what you mean, please tell is what exactly you want.

Upvotes: 0

Related Questions