Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I put a transformed scale on the right side of a ggplot2?

Tags:

r

ggplot2

I'm creating a graph showing the change in lake levels over time. I've attached a simple example below. I would like to add a scale (tick marks and annotation) on the right side of the plot that shows the elevation in feet. I know ggplot2 won't allow two different scales (see Plot with 2 y axes, one y axis on the left, and another y axis on the right), but because this is a transformation of the same scale, is there a way to do this? I'd prefer to keep using ggplot2 and not to have to revert to the plot() function.

library(ggplot2)
LakeLevels<-data.frame(Day=c(1:365),Elevation=sin(seq(0,2*pi,2*pi/364))*10+100)
p <- ggplot(data=LakeLevels) + geom_line(aes(x=Day,y=Elevation)) + 
  scale_y_continuous(name="Elevation (m)",limits=c(75,125)) 
p
like image 480
Bomhof Avatar asked Sep 24 '13 18:09

Bomhof


People also ask

How do you change the scale of an axis in R?

To change the axis scales on a plot in base R Language, we can use the xlim() and ylim() functions. The xlim() and ylim() functions are convenience functions that set the limit of the x-axis and y-axis respectively.

Are scales part of ggplot2?

The scales packages provides the internal scaling infrastructure used by ggplot2, and gives you tools to override the default breaks, labels, transformations and palettes.


1 Answers

You should have a look at this link http://rpubs.com/kohske/dual_axis_in_ggplot2.

I've adapted the code provided there for your example. This fix seems very "hacky", but it gets you part of the way there. The only piece left is figuring out how to add text to the right axis of the graph.

    library(ggplot2)
    library(gtable)
    library(grid)
    LakeLevels<-data.frame(Day=c(1:365),Elevation=sin(seq(0,2*pi,2*pi/364))*10+100)
    p1 <- ggplot(data=LakeLevels) + geom_line(aes(x=Day,y=Elevation)) + 
          scale_y_continuous(name="Elevation (m)",limits=c(75,125))

    p2<-ggplot(data=LakeLevels)+geom_line(aes(x=Day, y=Elevation))+
        scale_y_continuous(name="Elevation (ft)", limits=c(75,125),           
        breaks=c(80,90,100,110,120),
                 labels=c("262", "295", "328", "361", "394"))

    #extract gtable
    g1<-ggplot_gtable(ggplot_build(p1))
    g2<-ggplot_gtable(ggplot_build(p2))

    #overlap the panel of the 2nd plot on that of the 1st plot

    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)

   # draw it
   grid.draw(g)

enter image description here

like image 113
Walter Avatar answered Oct 12 '22 14:10

Walter