Thursday, October 30, 2014

10 30 2014 Dual Y Axis Graph (ggplot2) % Brooding vs Temperature Oyster Bay

Here I'm showing how to produce a dual Y axis graph with ggplot2 package in R. If you've tried to do this before you know it downright impossible. I found a great work around in the rpubs from a user named Hadley. Below is my code to produce a dual axis bar and line graph. I'm doing this to show the percent of animals brooding at each time point along with the associated temperature at that time point.  Broodperctemp.R
require(plyr)
## Loading required package: plyr
require(ggplot2)
## Loading required package: ggplot2
require(scales)
## Loading required package: scales
require(grid)
## Loading required package: grid
require(gtable)
## Loading required package: gtable
grid.newpage()
p1<-ggplot(data=oysbay, aes(x=Date, weight=Percent, colour=Pop, fill=Pop))+
  geom_bar(binwidth=10, position=position_dodge())+
  theme(axis.text.x=element_text(angle=90, size=10, vjust=0.5))+
  scale_colour_manual(values=c("blue","purple","orange"),labels=c("Dabob","Fidalgo","Oyster Bay"))+
  scale_fill_manual(values=c("blue","purple","orange"),labels=c("Dabob","Fidalgo","Oyster Bay"))+
  labs(x="Sample Date", y="Percent Brooding",title="Percent Brooding vs. Temperature")+
  theme_bw()+
  theme(legend.justification=c(0,1),
        legend.position=c(0,1),
        plot.title=element_text(size=30,vjust=1),
        axis.text.x=element_text(size=20),
        axis.text.y=element_text(size=20),
        axis.title.x=element_text(size=20),
        axis.title.y=element_text(size=20))
oysy1edit<-read.csv("TempData/oysY1fixed.csv")
oysy1edit$Date<-as.Date(oysy1edit$Date, "%m/%d/%Y")
oysmintemp<-ddply(oysy1edit,.(Date),summarise,min_temp=min(Temp,na.rm=T))
oysmintemprep<-subset(oysmintemp, Date>="2014-05-01"& Date<="2014-08-07")
p2<-ggplot()+geom_line(data=oysmintemprep,
            aes(x=Date, y=min_temp), color="red")+
  geom_hline(yintercept=12.5, color="forestgreen")+
  theme_bw() %+replace% 
  theme(panel.background = element_rect(fill = NA),
        panel.grid.major.x=element_blank(),
        panel.grid.minor.x=element_blank(),
        panel.grid.major.y=element_blank(),
        panel.grid.minor.y=element_blank(),
        axis.text.y=element_text(size=20,color="red"),
        axis.title.y=element_text(size=20))

g1<-ggplot_gtable(ggplot_build(p1))
g2<-ggplot_gtable(ggplot_build(p2))

pp<-c(subset(g1$layout,name=="panel",se=t:r))
g<-gtable_add_grob(g1, g2$grobs[[which(g2$layout$name=="panel")]],pp$t,pp$l,pp$b,pp$l)

ia<-which(g2$layout$name=="axis-l")
ga <- g2$grobs[[ia]]
ax <- ga$children[[2]]
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)

grid.draw(g)
plot of chunk unnamed-chunk-1


It's really important to note that I have subset the temperature data for only the daily minimums and  only from the date of the first sampling to the date of the last sampling. If you don't do this, the temp graph will be fit onto the graph regardless of whether it correlates to the dates on the x axis. My first version was really screwy because of this. Also note that for some reason when using this method you cannot create a legend for the line graph nor can you generate a title for the right hand y axis. It's not the best but it will make a good looking graph for you if you know these limitations.