Общая граница панели с cowplot и plot_grid
Я пытаюсь нарисовать границу вокруг двух графиков, которые были выровнены с plot_grid из пакета cowplot. Пожалуйста, смотрите следующий пример (модифицированный из виньетки "Изменение положения оси"):
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
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)
Теперь, вместо произвольно выбранных координат для красного поля, я бы хотел, чтобы он был выровнен по линиям оси. Я предполагаю, что эти координаты могут быть извлечены из вывода plot_grid, но я понятия не имею, как.
0 ответов
Основываясь на моем понимании гробов, я бы сказал, что проще получить координаты для каждого графика и добавить сегменты границ, прежде чем объединять графики, используя plot_grid
,
Пример данных:
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)
Функция для добавления соответствующих сегментов границы для каждого графа графика, где:
grob
является объектом grob, созданным с помощью ggplotGrob;sides
это строка символов, содержащая любую комбинацию"t"
/"l"
/"b"
/"r"
в любом порядке указать желаемые стороны для размещения границы;col
желаемый цвет рамки (по умолчанию красный);...
для любых других параметров, которые будут переданы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)
}
Использование:
plot_grid(add.segments(g1, "tlr"),
add.segments(g2, "lbr"),
ncol = 1, align = "v")
Другой пример, для выравнивания двух графиков по горизонтали (хорошо, нет смысла выравнивать эти конкретные графики рядом, но вы поняли идею):
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")