questions regarding scale_x_datetime, grouping, facetting etc

75 views
Skip to first unread message

ravi

unread,
Jan 8, 2010, 11:49:49 AM1/8/10
to ggp...@googlegroups.com
Hi,
I first started out by working on a problem in using the scale_x_datetime function. After experimenting, I found a partial solution. I did more experimenting and stumbled onto other problems as well. I would like to take up all these questions now and find out if there are other more efficient approaches in doing what I have attempted. I show below first the R code that I used (a simulated version of my actual problem).

#construct a time series
strt<-as.POSIXct("2009-11-05 12:00:00 CET")
endd<-as.POSIXct("2009-11-06 13:00:00 CET")
timeP<-seq(strt,endd,by="144 sec")
# construct three random variables for plotting
lt1<-length(timeP)
a1<-runif(lt1,0,1)
a2<-runif(lt1,10,100)
a3<-runif(lt1,100,1000)
# pull them together in a data frame
df<-data.frame(tP=timeP,a1,a2,a3)
# get the average for every hour
timeL<-as.POSIXlt(timeP)
df$hr<-timeL$hour;df$dy<- timeL$mday
df2<-ddply(df,.(dy,hr),transform,av1=mean(a1),av2=mean(a2),av3=mean(a3))
# It appears to be difficult to plot using the scale_x_datetime in ggplot
# We attempt a workaround using scale_x_continuous
# df2$t converted to numeric class
df2$tN<-as.numeric(df2$tP)
# Also, prepare for constructing the axis labels
tP1<-df2$tP[1];tP2<-df2$tP[length(df2$tP)]
hrsP<-seq(tP1,tP2,by="4 hour")
# Converted to as.POSIXlt for extracting the whole hour only from the vector
hrsL<-as.POSIXlt(hrsP)
# Converted to numeric class for identifying the axial tickmark locations
hrsN<-as.numeric(hrsP)
axticks<-hrsN
# Extract the hour for labelling purposes
lh<-hrsL$hour
# Paste together the character label
lbls<-paste(lh,"00",sep=":")
#melt the data frame and prepare for facetting and grouping
dfm<-melt(df2,id.var=c("tP","tN","dy","hr"))
dfm$bx<-combine_factor(dfm$variable,c(1:3,1:3))
levels(dfm$bx)<-c("b1","b2","b3")
dfm$gp<-combine_factor(dfm$variable,c(rep(1,3),rep(2,3)))
levels(dfm$gp)<-c("var","av")
#Inspect the data frame
ld<- nrow(dfm)
ld1<-sample(ld,10,replace=FALSE)
dfm[ld1,]
# Actual plotting :
g1<-ggplot(data=dfm,aes(x=tN,y=value,group=gp,colour=gp))+ facet_grid(bx~.,scale="free_y")
g2<-g1+geom_line()
g3<-g2+scale_x_continuous(breaks=axticks,labels=lbls)
g4<-g3+xlab("Hour of Day")+ylab("Variable")

I would like to get clarifications on the following points :
1. I was unable to plot using the scale_x_datetime function. Instead, I have used a workaround by converting the time series vector of POSIXct class to a numeric one (also to the POSIXlt class for constructing the axis labels). I then used the scale_x_continuous function for plotting the time series. Is there a simpler and more direct method that I have missed?
2. I have six different y variables (a1,a2,a3,av1,av2,a3) to plot versus the time series on the x-axis. I want to get a stack of 3 plots with a1 and av1 on the first plot, a2 and av2 on the second etc. I have resorted to constructing extra variables for grouping and facetting (followed by using the melt function on the data frame). The procedure that I have followed seems to be a rather roundabout procedure. Is there a simpler and more direct method?
3. I want to manually select the colours of the lines. For example, I want a black colour for the variables a1 to a3 and red for av1 to av3. How do I set this? It seems to me that it is possible only to choose one scale setting for a plot. i.e. I did not seem to succeed with use of scale_colour_manual after using scale_x_continuous. Is this so?
4. Suppose, I want to use geom_line for a1 to a3 and geom_line for av1 to av3. How do I do that?
4. In my data, all the y vectors a1 to a3 share a common frquency. It was easy to construct a data frame with these vectors. How should I treat the case where they have different frequencies and different time series instants. How should I go about constructing a similiar facetted and grouped plot with three different data frames with the same total time period, but with different time instants and frequencies (may even be irregular series).

It would be helpful to at least get some hints before proceeding with my trials. Detailed explanations would, of course, be most welcome.
Thanking you,
Ravi

ggExample.jpeg

hadley wickham

unread,
Jan 8, 2010, 2:19:46 PM1/8/10
to ravi, ggp...@googlegroups.com
> I would like to get clarifications on the following points :
> 1. I was unable to plot using the scale_x_datetime function. Instead, I have used a workaround by converting the time series vector of POSIXct class to a numeric one (also to the POSIXlt class for constructing the axis labels). I then used the scale_x_continuous function for plotting the time series. Is there a simpler and more direct method that I have missed?

> 3. I want to manually select the colours of the lines. For example, I want a black colour for the variables a1 to a3 and red for av1 to av3. How do I set this? It seems to me that it is possible only to choose one scale setting for a plot. i.e. I did not seem to succeed with use of scale_colour_manual after using scale_x_continuous. Is this so?

What did you try? The following works fine for me?

ggplot(data=dfm,aes(tN, value, colour = gp))+
geom_line() +
facet_grid(bx ~ ., scale = "free_y") +
scale_x_datetime(major = "4 hours") +
scale_colour_manual(values = c("var" = "grey50", av = "black"))

> 2. I have six different y variables (a1,a2,a3,av1,av2,a3) to plot versus the time series on the x-axis. I want to get a stack of 3 plots with a1 and av1 on the first plot, a2 and av2 on the second etc. I have resorted to constructing extra variables for grouping and facetting (followed by using the melt function on the data frame). The procedure that I have followed seems to be a rather roundabout procedure. Is there a simpler and more direct method?

That may be the simplest way, depending on how you get the data.

> 4. Suppose, I want to use geom_line for a1 to a3 and geom_line for av1 to av3. How do I do that?

What do you mean?

> 4. In my data, all the y vectors a1 to a3 share a common frquency. It was easy to construct a data frame with these vectors. How should I treat the case where they have different frequencies and different time series instants. How should I go about constructing a similiar facetted and grouped plot with three different data frames with the same total time period, but with different time instants and frequencies (may even be irregular series).

The ggplot code would be the same.

Hadley

--
http://had.co.nz/

ravi

unread,
Jan 11, 2010, 10:22:17 AM1/11/10
to hadley wickham, ggp...@googlegroups.com
Hi,
Thanks a lot, Hadley. From your reply to point 3, I now understand how the scale_colour_manual function can be adapted to choose my own colours.
I would like to follow up with a few more questions :

1. Actually, point 4 in my earlier query should have read : Suppose, I want to use geom_point for the variables a1 to a3 and geom_line for av1 to av3. How do I do that?
I tried the following  (attempted changes are in g2):
g1<-ggplot(data=dfm,aes(x=tN,y=value,colour=gp))+ facet_grid(bx~.,scale="free_y")
g2<-g1+geom_point(subset(dfm,gp=="var"))+geom_line(subset(dfm,gp=="av"))
g3<-g2+scale_x_continuous(breaks=axticks,labels=lbls)
g4<-g3+xlab("Hour of Day")+ylab("Variable")+scale_colour_manual("Variables",values = c("var" = "grey50", "av" = "black"))
I get the following error message :
> g2<-g1+geom_point(subset(dfm,gp=="var"))+geom_line(subset(dfm,gp=="av"))
Error in get("new", env = Layer, inherits = TRUE)(Layer, ...) :
  Mapping should be a list of unevaluated mappings created by aes or aes_string
Please let me know how to choose geom_point for some variables, and geom_line for others, from a data frame with an elaborate structure as in dfm.

2. My next question starts with the code in my earlier mail (with the addition of Hadley's suggestion). Suppose that I have a second data frame with the same structure as the first. Can I use the "layer" concept and superpose the new plots from the 2nd data frame on top of the old plot? I don't actually have practical use of such an example right now. It is more for understanding the "grammar" better. My new question starts with the following additions :

bv1<-df2$av1+0.3
bv2<-df2$av2+30
bv3<-df2$av3+300
df3<-data.frame(tP=df2$tP,tN=df2$tN,bv1,bv2,bv3)
dfm2<-melt(df3,id.var=c("tP","tN"))
dfm2$bx<-combine_factor(dfm2$variable,c(1:3))
levels(dfm2$bx)<-c("b1","b2","b3")
dfm2$gp<-combine_factor(dfm2$variable,c(rep(1,3)))
levels(dfm2$gp)<-"bv"
g5<-g4 %+% dfm2
Gives an error message.
I can, of course, start from the beginning, include the new variables in the original data frame and get the plot that I want. But I just want to know how far I can stretch the "layer" option.
3. Supposing that I have just the variable, bv3. Is there a way of including a plot of this extra variable in a chosen grid position? I guess that I should really use viewports if I want to do that. But again, I just want to know if the facetting option has more to offer than is apparent from a first reading.
4. My final question involves the term, "grammar of graphics". I don't really understand the mapping from grammar to graphics. Just how far does the analogy hold? In the ggplot2 book, as far as I can make out, the metaphor is not really explained. It just alludes to the "grammar" as the underlying theory of the ggplot2 approach. I just wonder if this can be explained with some simple, concrete examples. I am trying to get hold of Wilkinson's book. Meanwhile, I will be grateful if I can be directed to other references/links with more detailed explanations.
Thanking you,
Ravi

baptiste auguie

unread,
Jan 11, 2010, 11:50:50 AM1/11/10
to ravi, ggp...@googlegroups.com
Hi,

On Mon, Jan 11, 2010 at 4:22 PM, ravi <rv...@yahoo.se> wrote:

> g2<-g1+geom_point(subset(dfm,gp=="var"))+geom_line(subset(dfm,gp=="av"))

This cannot work because geom_xxx() expects a mapping as first
argument, not data. You could use named arguments,

geom_point(data = subset(dfm,gp=="var"))

HTH,

baptiste

Reply all
Reply to author
Forward
0 new messages