-1

I have a specific issue (at least I like to think that :)). I want to align three plots in two columns and two rows. The alignment should be after the central plot (see pic; plot C) where plot A should align after x-axis of plot C and plot D should align after y-axis of plot C. Note, there is no plot B, this should stay empty.

Data:

a <- data.frame(
  id = 1:15,
  GO = c(
    "phosphoglycerate kinase", "phosphoglycerate kinase", 
    "phosphoglycerate kinase", "phosphoglycerate kinase", "phosphoglycerate kinase", 
    "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", 
    "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", "allantoicase", 
    "allantoicase", "allantoicase", "allantoicase", "allantoicase"),
  variable = c(
    "d64", "d31", "d16", "d9", "d0", "d64", "d31", "d16", "d9", "d0", "d64", "d31", "d16", "d9", "d0"),
  value = c(
    154.28239, 226.04355, 245.67728, 271.82375, 270.83519, 289.01809, 491.66461,
    485.28291, 351.3759, 510.96043, 22.75253, 31.66546, 129.50564, 206.6651, 32.43769),
  relAbundByGO = c(
    13.201624, 19.342078, 21.022096, 23.259395, 23.174806, 13.57975, 23.101262,
    22.801413, 16.509683, 24.007892, 5.378513, 7.485456, 30.614078, 48.853948, 7.668005),
  GOd = c(
    "phosphoglycerate kinase", "phosphoglycerate kinase", 
    "phosphoglycerate kinase", "phosphoglycerate kinase", "phosphoglycerate kinase", 
    "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", 
    "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", "allantoicase", 
    "allantoicase", "allantoicase", "allantoicase", "allantoicase"
  ))

b <- data.frame(
  id = 1:15,
  Compound = c(
    "C5-C10", "C5-C10", "C5-C10", 
    "C5-C10", "C5-C10", "C10-C20", "C10-C20", "C10-C20", "C10-C20", 
    "C10-C20", "BTEX", "BTEX", "BTEX", "BTEX", "BTEX"),
  Degradation = c(
    100, 100, 23.5, 5.6, 0, 100, 100, 67.2, 19, 0.6, 100, 100, 88.7, 43.3, 0.1),
  st ()dev = c(
    0, 0, 35, 12.4, 0, 0, 0, 19.3, 13.1, 0.6, 0, 0, 33.4, 43.4, 0.2),
  day = c(
    "NSWOD-0", "NSWOD-64", "NSOD-9", 
    "NSOD-16", "NSOD-31", "NSWOD-0", "NSWOD-64", "NSOD-9", "NSOD-16", 
    "NSOD-31", "NSWOD-0", "NSWOD-64", "NSOD-9", "NSOD-16", "NSOD-31"))

This is a try with cowplot:

a$GO <- factor(a$GO, levels = a$GO) #keep the same order as in table
a$variable <- factor(a$variable, levels = c("d0", "d64", "d9", "d16", "d31"))
p1 <- ggplot(data = a, aes(x=variable, y=GO)) + 
  geom_tile(aes(fill=relAbundByGO), colour = "white") + ylab("Gene ontology") + 
  scale_fill_gradient(name="Relative\nabundance of TPM", low = "green", high = "red", limits=c(0, 100), na.value="transparent") +
  scale_x_discrete("Sample", 
                   breaks = c("d0", "d64", "d9", "d16", "d31"),
                   labels = c("CTRL-0", "CTRL-64", "CEWAF-9","CEWAF-16","CEWAF-31")) + 
  theme(legend.position="left")
p1

a$GO <- factor(a$GO, levels = a$GO) #keep the same order as in table
p2 <- ggplot(data = a, aes(x=GO, y=value)) +
  geom_bar(stat = "identity") +
  theme(axis.text.x = element_text(angle = 0)) +
  ylab("Cumulative TPM abundance") +
  theme(axis.text.y=element_blank(),
        axis.title.y=element_blank()) +
  coord_flip()
p2

b$day <- factor(b$day, levels = b$day) #keep the same order as in table
p3 <- ggplot(b, aes(x=day, y=Degradation, color=Compound, group=Compound)) + 
  geom_point(size=4, shape=21, fill="white") + 
  geom_line(size=0.7) + 
  ylab("Hydrocarbon content (%)") + 
  geom_errorbar(aes(ymax=Degradation + stdev, ymin=Degradation-stdev), linetype="dashed", lwd=.6, width=.4) +
  theme_bw(base_size = 12, base_family = "Helvetica") +
  theme(axis.text.x=element_blank()
        ,axis.ticks=element_blank()
        ,axis.title.x=element_blank(),
        legend.position="left") + 
  scale_color_discrete(name="Hydrocarbon\ngroup",
                       breaks=c("C5-C10", "C10-C20", "BTEX", "PAHs"))
p3

legend_p1 <- get_legend(p1)
legend_p3 <- get_legend(p3)

p1 <- p1 + theme(legend.position='none')
p3 <- p3 + theme(legend.position='none')

cowplot::plot_grid(
  cowplot::plot_grid(legend_p3, legend_p1, ncol = 1),
  cowplot::plot_grid(p3, NULL, p1, p2,  ncol = 2, nrow = 2, rel_widths = c(1, 0.75, 1, 0.75), labels = c('A', '', 'C', 'D'), align = "hv"),
  rel_widths = c(0.16, 1))

enter image description here

I would like to have plot D very close to plot C

Deni

  • Are you using the same values for x-axis of A and C? See this example, it is all nicely alligned: `library(ggplot2); library(cowplot); a <- ggplot(cars, aes(x = speed)) + geom_bar(); c <- ggplot(cars, aes(x = speed, y = dist)) + geom_point(); d <- ggplot(cars, aes(x = dist, y = speed)) + geom_point(); plot_grid(a, NULL, c, d, ncol = 2, nrow = 2, rel_widths = c(10/16, 6/16, 10/16, 6/16), labels = c('A', '', 'C', 'D'), align = "hv")` – m-dz Mar 06 '17 at 15:32
  • 3
    _"Hope someone can try to reproduce something"_, uhm, I think it's on you to give a reproducible example. Do you get a message or warning about alignment? – Axeman Mar 06 '17 at 15:32
  • @m-dz, the plotting areas will/should align regardless of x-axis values. The legends may provide problems though. – Axeman Mar 06 '17 at 15:34
  • 1
    @Axeman, looks like I missunderstood how `cowplot` alignment works, thanks for correcting me. From the plot looks like it is aligning whole plots, with legends and axis labels included. Would be easier to have [a reproducible example, as described here](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). – m-dz Mar 06 '17 at 15:59
  • @m-dz yes, these are the same axis values, as well as C and D have the same y axis values. You just made the same approach where the alignment is not working in my case. – Deni Galinac Ribičić Mar 06 '17 at 16:19
  • @Axeman I'll try to filter out some of the data and post it to give a reproducible example. And yes, there are warning messages, one important at the end stating it was not possible to align vertically:7: In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) else paste0(labels, : duplicated levels in factors are deprecated 8: In plot_grid(p2, NULL, p1, p5, ncol = 2, nrow = 2, rel_widths = c(10/16, : Graphs cannot be vertically aligned. Placing graphs unaligned. – Deni Galinac Ribičić Mar 06 '17 at 16:19
  • You can use one of the standard datasets like `mtcars`. – m-dz Mar 06 '17 at 16:38
  • @m-dz I've provided now part of the data which is able to reproduce the problem. – Deni Galinac Ribičić Mar 06 '17 at 16:45
  • Please use `dput()` so the data can be pasted directly into R. – m-dz Mar 06 '17 at 16:57
  • @m-dz sorry for that, should be fine now. – Deni Galinac Ribičić Mar 06 '17 at 17:21

1 Answers1

1

As @Axeman mentioned, it is caused by legends, cowplot::get_legend() can fix this (see ?cowplot::get_legend() for your exact case):

legend_p1 <- get_legend(p1)
legend_p3 <- get_legend(p3)

p1 <- p1 + theme(legend.position='none')
p3 <- p3 + theme(legend.position='none')

cowplot::plot_grid(
  cowplot::plot_grid(legend_p1, legend_p3, ncol = 1),
  cowplot::plot_grid(p3, NULL, p1, p2,  ncol = 2, nrow = 2, rel_widths = c(1, 0.75, 1, 0.75), labels = c('A', '', 'C', 'D'), align = "hv"),
  rel_widths = c(0.1, 1))

but it needs quite a lot of work to make it "readable".

Data ("raw", apply all transformations from the OP postt):

a <- data.frame(
  id = 1:15,
  GO = c(
    "phosphoglycerate kinase", "phosphoglycerate kinase", 
    "phosphoglycerate kinase", "phosphoglycerate kinase", "phosphoglycerate kinase", 
    "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", 
    "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", "allantoicase", 
    "allantoicase", "allantoicase", "allantoicase", "allantoicase"),
  variable = c(
    "d64", "d31", "d16", "d9", "d0", "d64", "d31", "d16", "d9", "d0", "d64", "d31", "d16", "d9", "d0"),
  value = c(
    154.28239, 226.04355, 245.67728, 271.82375, 270.83519, 289.01809, 491.66461,
    485.28291, 351.3759, 510.96043, 22.75253, 31.66546, 129.50564, 206.6651, 32.43769),
  relAbundByGO = c(
    13.201624, 19.342078, 21.022096, 23.259395, 23.174806, 13.57975, 23.101262,
    22.801413, 16.509683, 24.007892, 5.378513, 7.485456, 30.614078, 48.853948, 7.668005),
  GOd = c(
    "phosphoglycerate kinase", "phosphoglycerate kinase", 
    "phosphoglycerate kinase", "phosphoglycerate kinase", "phosphoglycerate kinase", 
    "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", 
    "phenylalanine-tRNA ligase", "phenylalanine-tRNA ligase", "allantoicase", 
    "allantoicase", "allantoicase", "allantoicase", "allantoicase"
  ))
b <- data.frame(
  id = 1:15,
  Compound = c(
    "C5-C10", "C5-C10", "C5-C10", 
    "C5-C10", "C5-C10", "C10-C20", "C10-C20", "C10-C20", "C10-C20", 
    "C10-C20", "BTEX", "BTEX", "BTEX", "BTEX", "BTEX"),
  Degradation = c(
    100, 100, 23.5, 5.6, 0, 100, 100, 67.2, 19, 0.6, 100, 100, 88.7, 43.3, 0.1),
  st ()dev = c(
    0, 0, 35, 12.4, 0, 0, 0, 19.3, 13.1, 0.6, 0, 0, 33.4, 43.4, 0.2),
  day = c(
    "NSWOD-0", "NSWOD-64", "NSOD-9", 
    "NSOD-16", "NSOD-31", "NSWOD-0", "NSWOD-64", "NSOD-9", "NSOD-16", 
    "NSOD-31", "NSWOD-0", "NSWOD-64", "NSOD-9", "NSOD-16", "NSOD-31"))
m-dz
  • 2,342
  • 17
  • 29
  • Thanks a lot! this looks now more to what I really want. Could you point me towards the best way to make respective data transformation? – Deni Galinac Ribičić Mar 06 '17 at 23:18
  • No problem! I ma not sure what you mean by a 'respective data transformation', could you explain, maybe add an example to your question above? – m-dz Mar 07 '17 at 07:09
  • I just meant is there a neat way to tweak the data from original post to what you've created for "readable" plotting? – Deni Galinac Ribičić Mar 07 '17 at 09:21
  • Not really, by making plots "readable" I meant to tweak the `rel_widths` etc., you can also shorten the `GO` and `GOd` so they won't use so much space. What else... if plot `D` is only to show volume comparison you may try to remove x-axis. It is all just to fix the "visual" side of the plots. – m-dz Mar 07 '17 at 09:59
  • Thanks for help! One more thing, actually two :) When plotting I would like to keep plot D as close as possible to plot C, can this be done? Now they are pretty much apart. There is also a "GOd" label hovering after plot A, I would like to have that removed. Thanks again. – Deni Galinac Ribičić Mar 07 '17 at 14:33
  • Please edit your question with the exact code you are using currently so others can see the plot and help - I will have a look as well! – m-dz Mar 07 '17 at 15:29
  • please find the edited code. The "hovering label" I was talking about does not appear in this reproducible example, but only when I use the whole dataset (have to figure out on my own why does it happen). Still I would like to have plot D closer to plot C, since labels of y axis of plot C correspond y axis of plot D. – Deni Galinac Ribičić Mar 08 '17 at 12:18
  • A quick thought worth checking: please rename the y-axis values of plot C to something shorter (even 'a', 'b' and 'c') and see how plot D behaves. – m-dz Mar 08 '17 at 12:53
  • Yeap, it's coming closer together. Could this be forced with longer y-axis values? – Deni Galinac Ribičić Mar 08 '17 at 13:01
  • It is, see here http://imageshack.com/a/img923/1530/q83EXH.png, but I cannot look at it now unfortunately. – m-dz Mar 08 '17 at 14:42