The border of the common panel with a chest of drawers and plot_grid

I am trying to draw a border around two graphs that were aligned with plot_grid from the cowplot package. Please see the following example (modified from the "Repositioning the axis" vignette ):

 require(gtable) require(cowplot) # top plot p1 <- ggplot(mtcars, aes(mpg, disp)) + geom_line(colour = 'blue') + background_grid(minor = 'none') g1 <- switch_axis_position(p1, 'xy') # switch both axes g1 <- gtable_squash_rows(g1, length(g1$height)) # set bottom row to 0 height # bottom plot p2 <- ggplot(mtcars, aes(mpg, qsec)) + geom_line(colour = 'green') + ylim(14, 25) + background_grid(minor = 'none') g2 <- ggplotGrob(p2) g2 <- gtable_add_cols(g2, g1$widths[5:6], 4) # add the two additional columns that g1 has g2 <- gtable_squash_rows(g2, 1:2) # set top two rows to 0 height plot_grid(g1, g2, ncol = 1, align = 'v') + annotate("rect", xmin = 0.1, xmax = 0.9, ymin = 0.1, ymax = 0.9, color = "red", fill = NA) 

example

Now, instead of arbitrarily selected coordinates for the red field, I would like it to be aligned along the axis lines. I assume that these coordinates can be extracted from the plot_grid output, but I have no idea how.

+6
source share
1 answer

Based on my understanding of the coffins, I would say that it’s easier to get the coordinates for each graph and add border segments before combining the graphs with plot_grid .

Sample data :

 library(gtable) library(cowplot) # sample plots # (note: the cowplot function switch_axis_position has been deprecated, as its # creator notes ggplot2 now natively supports axes on either side of the plot.) p1 <- ggplot(mtcars, aes(mpg, disp)) + geom_line(colour = 'blue') + scale_x_continuous(position = "top") + scale_y_continuous(position = "right") + background_grid(minor = 'none'); p1 p2 <- ggplot(mtcars, aes(mpg, qsec)) + geom_line(colour = 'green') + ylim(14, 25) + background_grid(minor = 'none'); p2 # convert to grob objects g1 <- ggplotGrob(p1) g2 <- ggplotGrob(p2) 

Function for adding the corresponding border segments for each graph graph, where:

  • grob - a grob object created using ggplotGrob;
  • sides - a character string containing any combination of "t" / "l" / "b" / "r" in any order to indicate the desired sides to place the border;
  • col - desired border color (red by default);
  • ... for any other parameters passed by gpar() to segmentsGrob() gpar() segmentsGrob()

,

 library(grid) add.segments <- function(grob, sides = "tlbr", col = "red", ...){ # get extent of gtable cells to be surrounded by border panel.coords <- g1[["layout"]][g1[["layout"]][["name"]] == "panel", ] t <- if(grepl("t", sides)) panel.coords[["t"]] else 1 b <- if(grepl("b", sides)) panel.coords[["b"]] else length(grob[["heights"]]) l <- if(grepl("l", sides)) panel.coords[["l"]] else 1 r <- if(grepl("r", sides)) panel.coords[["r"]] else length(grob[["widths"]]) # define border coordinates, & filter for the desired border sides coords <- data.frame(direction = c("t", "b", "l", "r"), x0 = c(0, 0, 0, 1), y0 = c(1, 0, 0, 0), x1 = c(1, 1, 0, 1), y1 = c(1, 0, 1, 1), stringsAsFactors = FALSE) coords <- coords[sapply(coords$direction, grepl, sides), ] # add desired border sides as segments to the grob at specific gtable cells grob <- gtable_add_grob(x = grob, grobs = segmentsGrob( x0 = coords[["x0"]], y0 = coords[["y0"]], x1 = coords[["x1"]], y1 = coords[["y1"]], gp = gpar(col = col, ...) ), t = t, l = l, b = b, r = r, clip = "off", name = "segments") return(grob) } 

Usage :

 plot_grid(add.segments(g1, "tlr"), add.segments(g2, "lbr"), ncol = 1, align = "v") 

plot

Another example is to align two graphs horizontally (well, it makes no sense to align these specific graphs side by side, but you get the idea):

 plot_grid(add.segments(g2, "tlb", col = "gold2", lty = 2, lwd = 5), add.segments(g1, "trb", col = "gold2", lty = 2, lwd = 5), nrow = 1, align = "h") 

plot 2

0
source

Source: https://habr.com/ru/post/1245592/


All Articles