1

I have two graphs that I'm trying to merge with dual y axes. I'm having trouble getting rid of that space between the two legends that I am trying to merge. Here are my two graphs:

require(ggplot2)
download.file("https://www.dropbox.com/s/y6qg4432x2l2hbr/data1.csv?dl=1","data1.csv")
download.file("https://www.dropbox.com/s/jv5iuarx1qa3vzf/data2.csv?dl=1","data2.csv")
data1<-read.csv("data1.csv")
data2<-read.csv("data2.csv")

> head(data1)  # https://www.dropbox.com/s/y6qg4432x2l2hbr/data1.csv?dl=1 
  base pos    type    values labels valueme2
1    A   1  mean_r 1.0200473   2771 13.56172
2    A   1 quant_r 0.6450000   2771 13.56172
4    C   1  mean_r 6.1059971    343 56.25043
5    C   1 quant_r 3.5411200    343 56.25043
7    G   1  mean_r 0.9848452     84 13.26626
8    G   1 quant_r 0.5639600     84 13.26626

> head(data2)  # https://www.dropbox.com/s/jv5iuarx1qa3vzf/data2.csv?dl=1
   base pos  type     values labels valueme2
3     A   1 p_val  0.7653560   2771 13.56172
6     C   1 p_val 51.2504280    343 56.25043
9     G   1 p_val  0.3350526     84 13.26626
12    T   1 p_val  2.0327415   2770 13.56881
15    A   2 p_val 51.2504280    343 56.25043
18    C   2 p_val  0.5417566    484 13.27813

prettify <- theme(panel.background = element_rect(fill = NA), 
                            panel.grid.major.y = element_blank(),
                            panel.grid.major.x = element_line(size=.1, color="gray",linetype="dotted"), 
                            panel.grid.minor.y = element_blank(),
                            panel.grid.minor.x = element_line(size=.1, color="gray"))

graphme1 <- ggplot(data1, aes(x = base, y = values, colour = type, group = type)) + 
            geom_line(size=1.3) + facet_wrap( ~ pos, ncol = 7) + 
            scale_color_manual(values=c("#7CAE00", "#00BFC4")) + 
            theme_bw() %+replace% prettify +
            theme(legend.position="bottom")

graphme2 <- ggplot(data2, aes(x = base, y = values, colour = "p_val", group = type)) + 
            geom_text(aes(y=(valueme2 + 0.3),label = labels, size = 1), colour="black",alpha=0.65,show_guide=F) + 
            geom_line(size=1.3) + facet_wrap( ~ pos, ncol = 7) + 
            theme_bw() %+replace% prettify +
            theme(legend.position="bottom")

And below is how I'm merging the two:

      g1 <- ggplot_gtable(ggplot_build(graphme1))
      g2 <- ggplot_gtable(ggplot_build(graphme2))

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

      ia <- which(grepl("axis_l",g2$layout$name) |  grepl("axis-l",g2$layout$name)     )
      ga <- g2$grobs[ia]

      axis_idx <- as.numeric(which(sapply(ga,function(x) !is.null(x$children$axis))))

      for(i in 1:length(axis_idx)){
        ax <- ga[[axis_idx[i]]]$children$axis
        ax$widths <- rev(ax$widths)
        ax$grobs <- rev(ax$grobs)
        ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(0.9, "npc") + unit(0.16, "cm")
        g <- gtable_add_cols(g, g2$widths[g2$layout[ia[axis_idx[i]], ]$l], length(g$widths) - 1)
        g <- gtable_add_grob(g, ax, pp$t[axis_idx[i]], length(g$widths) - i, pp$b[axis_idx[i]])
      }
      leg1 <- g1$grobs[[which(g1$layout$name == "guide-box")]]
      leg2 <- g2$grobs[[which(g2$layout$name == "guide-box")]]

      g$grobs[[which(g$layout$name == "guide-box")]] <- gtable:::cbind_gtable(leg1, leg2, "first")
      grid.newpage()
      grid.draw(g)

graphme1

enter image description here

graphme2

enter image description here

merged

enter image description here

In this last picture you can see the gap between the two legends that I'm trying to merge. If possible I would also like to get rid of the "p_val" title and combine both legends under one name "type"

Dhawal Kapil
  • 2,584
  • 18
  • 31
alki
  • 3,334
  • 5
  • 22
  • 45
  • Can you make your example reproducible? – Roman Luštrik Sep 13 '15 at 07:08
  • @RomanLuštrik Sure, here is a link to data1: https://www.dropbox.com/s/y6qg4432x2l2hbr/data1.csv?dl=0 and here is a link to data2: https://www.dropbox.com/s/jv5iuarx1qa3vzf/data2.csv?dl=0 – alki Sep 13 '15 at 07:14
  • Please include all the relevant data in your post. Linking to an offsite resource makes it potentially less useful in the future. – Roman Luštrik Sep 13 '15 at 07:15
  • 1
    Thanks I'll keep that in mind. I've added head(data1) and head(data2) to the post – alki Sep 13 '15 at 07:18
  • Looking at your data, the most simple thing to do is just `rbind(data1, data2)` and then make the plot. – Jaap Sep 13 '15 at 07:24
  • I did that at first, however the value columns of data2 and data1 differed too much which was why I decided to use two y axes. The highest data2$values go up to is ~50 while that of data1$values is only ~6 – alki Sep 13 '15 at 07:26
  • i think you have a bigger problem here..if you look `graphme2` the peak of your `p_val` in `1` is `~50` but after combining the graphs its showing more or less to `~6`. Do you think `graphme2` was wrongly scaled while merging. As mentioned by @Jaap rbinding would be the appropriate thing to do even if data varies too much because that is how your data is. Since there are three factor variables in your data do you think there can be better representation of these graphs? – Dhawal Kapil Sep 13 '15 at 08:09
  • @DhawalKapil see my answer for an alternative solution – Jaap Sep 13 '15 at 09:01
  • Yes..correctly done..!! – Dhawal Kapil Sep 13 '15 at 09:03
  • @Chani I haven't seen a reaction of you yet on my answer. If you have any questions, please let me know. – Jaap Sep 13 '15 at 20:07
  • Thanks for the answer, I just got a chance to see it. Your way of visualizing the data is much cleaner and easier to understand! – alki Sep 14 '15 at 00:58

1 Answers1

3

Using two y-axis with different scales is often not a good idea for visualizing data. In your example it will make the readers think that p_val is mostly equivalent to mean_r (which is not the case).

As I said in the comments, the best thing to do is combine the data into one dataframe and then make your plot:

dat12 <- rbind(data1,data2)

ggplot(dat12, aes(x = base, y = values, colour = type, group = type)) + 
  geom_line(size=1) + 
  facet_grid(. ~ pos) + 
  theme_bw() + 
  theme(panel.background = element_rect(fill = NA),
        panel.grid.major.y = element_blank(),
        panel.grid.major.x = element_line(size=.1, color="gray",linetype="dotted"),
        panel.grid.minor.y = element_blank(),
        panel.grid.minor.x = element_line(size=.1, color="gray"),
        legend.position="bottom")

which gives:

enter image description here

An alternative solution which might address your problem is using facet_grid with an x-variable and an y-variable:

ggplot(dat12, aes(x = base, y = values, color = type, group = type)) + 
  geom_line(size=1) + 
  facet_grid(type ~ pos, scales="free_y") + 
  theme_bw() + 
  theme(panel.background = element_rect(fill = NA),
        panel.grid.major.y = element_blank(),
        panel.grid.major.x = element_line(size=.1, color="gray",linetype="dotted"),
        panel.grid.minor.y = element_blank(),
        panel.grid.minor.x = element_line(size=.1, color="gray"),
        legend.position="bottom")

which gives:

enter image description here

Community
  • 1
  • 1
Jaap
  • 81,064
  • 34
  • 182
  • 193