Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dual y axis in ggplot2 for multiple panel figure

Tags:

r

ggplot2

We can not easily create the dual y axis with ggplot2.

  • kohske provided a solution to add dual y axis for single panel figures (http://rpubs.com/kohske/dual_axis_in_ggplot2)
  • @Andreas show an example to align two plots with ggplot2 (still single panel figures) (Plot with 2 y axes, one y axis on the left, and another y axis on the right)

These tricks can not work if figures have multiple panels (created by geom_wrap or geom_grid), e.g. 4 panel figure below. I would like to add the axis of p1 to the right side of panels of merged figure.

EDIT: I removed my codes here and post my own solution as an answer. Just in case some one needs it.

like image 417
Bangyou Avatar asked Feb 24 '14 07:02

Bangyou


People also ask

How do I get 2 y axis in ggplot2?

ggplot2 dual axes supportscale_x_continuous() and scale_y_continuous() can now display a secondary axis that is a one-to-one transformation of the primary axis (e.g. degrees Celcius to degrees Fahrenheit). The secondary axis will be positioned opposite to the primary axis and can be controlled with the sec.

How do I add a second Y axis in R?

Example: Create Plot with 2 Axes in R Let's deconstruct the code: par(mar = c(5, 4, 4, 4) + 0.3) – This code defines how much white space should be shown around the plot. It is important to leave enough space for the second y-axis. plot(x, y1, pch = 16, col = 2) – This code creates the first plot (i.e. the red dots).

How do you plot multiple Y axis?

Creating the Graph Select the required data. Select Plot > Multi-Panel/Axis: Multiple Y Axes.... Click the Multiple Y Axes... button on the 2D Graphs toolbar.


1 Answers

I post my own solution as an answer, just in case some one needs it.

library(ggplot2)
library(gtable)
library(grid)
df1 <- expand.grid(list(x = 1:10, z = 1:4, col = 1:2))
df2 <- df1
df1$y <- df1$x * df1$x + df1$col * 10
df2$y <- 4 * df2$x + df1$col * 10

p1 <- ggplot(df1)
p1 <- p1 + geom_point(aes(x, y, colour = factor(col)))
p1 <- p1 + facet_wrap(~z)
p1 <- p1 + ylab('Y label for figure 1')
p1 <- p1 + theme(legend.position = 'bottom',
    plot.margin = unit(c(1, 2, 0.5, 0.5), 'cm'))

p2 <- ggplot(df2)
p2 <- p2 + geom_line(aes(x, y, colour = factor(col)))
p2 <- p2 + facet_wrap(~z)
p2 <- p2 + ylab('Y label for figure 2')
p2 <- p2 + theme(legend.position = 'bottom',
    plot.margin = unit(c(1, 2, 0.5, 0.5), 'cm'))

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

combo_grob <- g2
pos <- length(combo_grob) - 1
combo_grob$grobs[[pos]] <- cbind(g1$grobs[[pos]],
    g2$grobs[[pos]], size = 'first')

panel_num <- length(unique(df1$z))
for (i in seq(panel_num))
{
    # grid.ls(g1$grobs[[i + 1]])
    panel_grob <- getGrob(g1$grobs[[i + 1]], 'geom_point.points',
        grep = TRUE, global = TRUE)
    combo_grob$grobs[[i + 1]] <- addGrob(combo_grob$grobs[[i + 1]], 
        panel_grob)
}       


pos_a <- grep('axis_l', names(g1$grobs))
axis <- g1$grobs[pos_a]
for (i in seq(along = axis))
{
    if (i %in% c(2, 4))
    {
        pp <- c(subset(g1$layout, name == paste0('panel-', i), se = t:r))

        ax <- axis[[1]]$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.5, "cm")
        ax$grobs[[2]]$x <- ax$grobs[[2]]$x - unit(1, "npc") + unit(0.8, "cm")
        combo_grob <- gtable_add_cols(combo_grob, g2$widths[g2$layout[pos_a[i],]$l], length(combo_grob$widths) - 1)
        combo_grob <- gtable_add_grob(combo_grob, ax,  pp$t, length(combo_grob$widths) - 1, pp$b)
    }
}

pp <- c(subset(g1$layout, name == 'ylab', se = t:r))

ia <- which(g1$layout$name == "ylab")
ga <- g1$grobs[[ia]]
ga$rot <- 270
ga$x <- ga$x - unit(1, "npc") + unit(1.5, "cm")

combo_grob <- gtable_add_cols(combo_grob, g2$widths[g2$layout[ia,]$l], length(combo_grob$widths) - 1)
combo_grob <- gtable_add_grob(combo_grob, ga, pp$t, length(combo_grob$widths) - 1, pp$b)
combo_grob$layout$clip <- "off"

grid.draw(combo_grob)

P1:

enter image description here

P2:

enter image description here

Merged:

enter image description here

like image 174
Bangyou Avatar answered Oct 21 '22 09:10

Bangyou