如何包含带状彩色组的图例
how to include the legend for strip colored-groups
我使用 here 提出的解决方案根据数据框提供的变量为使用 facet_wrap
创建的面条着色。
我需要添加条带颜色的图例 (size
),它绘制在 dummy
中。
知道如何从 g2$layout
或任何其他方式获取它吗?
library(gtable)
library(grid)
d <- data.frame(fruit = rep(c("apple", "orange", "plum", "banana", "pear", "grape")),
farm = rep(c(0,1,3,6,9,12), each=6),
weight = rnorm(36, 10000, 2500),
size=rep(c("small", "large")))
p1 = ggplot(data = d, aes(x = farm, y = weight)) +
geom_jitter(position = position_jitter(width = 0.3),
aes(color = factor(farm)), size = 2.5, alpha = 1) +
facet_wrap(~fruit)
dummy <- ggplot(data = d, aes(x = farm, y = weight))+ facet_wrap(~fruit) +
geom_rect(aes(fill=size), xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
theme_minimal()
g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(dummy)
gtable_select <- function (x, ...)
{
matches <- c(...)
x$layout <- x$layout[matches, , drop = FALSE]
x$grobs <- x$grobs[matches]
x
}
panels <- grepl(pattern="panel", g2$layout$name)
strips <- grepl(pattern="strip-t", g2$layout$name)
g2$layout$t[panels] <- g2$layout$t[panels] - 1
g2$layout$b[panels] <- g2$layout$b[panels] - 1
new_strips <- gtable_select(g2, panels | strips)
grid.newpage()
grid.draw(new_strips)
gtable_stack <- function(g1, g2){
g1$grobs <- c(g1$grobs, g2$grobs)
g1$layout <- transform(g1$layout, z= z-max(z), name="g2")
g1$layout <- rbind(g1$layout, g2$layout)
g1
}
new_plot <- gtable_stack(g1, new_strips)
grid.newpage()
grid.draw(new_plot)
从this answer借用以下函数,您可以先从虚拟图中提取图例。
# Extract only the legend from "dummy" plot
g_legend <- function(dummy){
tmp <- ggplot_gtable(ggplot_build(dummy))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}
# Assign the legend to a separate object
facet.legend <- g_legend(dummy)
然后您可以使用包 gridExtra
中的 grid.arrange()
...
library(gridExtra)
jpeg("plot-with-facet-legend.jpg", width = 8, height = 6, units = "in", res = 300)
print(grid.arrange(new_plot, facet.legend, nrow = 2, widths = c(7, 1), heights = c(6, 0.01)))
dev.off()
... 生成以下图:
或者:在执行相同的 jpeg(...)
、print(grid.arrange(...))
代码之前,直接从 g2
对象中获取图例的更紧凑的解决方案:
facet.legend <- g2$grobs[[which(sapply(g2$grobs, function(x) x$name) %in% "guide-box")]]
当然,您可以尝试使用 widths
和 heights
参数来生成更整洁的图,并且可能存在另一种解决方案,它比我的更简单一些,但希望如此这至少大致就是您所寻求的。
我使用 here 提出的解决方案根据数据框提供的变量为使用 facet_wrap
创建的面条着色。
我需要添加条带颜色的图例 (size
),它绘制在 dummy
中。
知道如何从 g2$layout
或任何其他方式获取它吗?
library(gtable)
library(grid)
d <- data.frame(fruit = rep(c("apple", "orange", "plum", "banana", "pear", "grape")),
farm = rep(c(0,1,3,6,9,12), each=6),
weight = rnorm(36, 10000, 2500),
size=rep(c("small", "large")))
p1 = ggplot(data = d, aes(x = farm, y = weight)) +
geom_jitter(position = position_jitter(width = 0.3),
aes(color = factor(farm)), size = 2.5, alpha = 1) +
facet_wrap(~fruit)
dummy <- ggplot(data = d, aes(x = farm, y = weight))+ facet_wrap(~fruit) +
geom_rect(aes(fill=size), xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
theme_minimal()
g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(dummy)
gtable_select <- function (x, ...)
{
matches <- c(...)
x$layout <- x$layout[matches, , drop = FALSE]
x$grobs <- x$grobs[matches]
x
}
panels <- grepl(pattern="panel", g2$layout$name)
strips <- grepl(pattern="strip-t", g2$layout$name)
g2$layout$t[panels] <- g2$layout$t[panels] - 1
g2$layout$b[panels] <- g2$layout$b[panels] - 1
new_strips <- gtable_select(g2, panels | strips)
grid.newpage()
grid.draw(new_strips)
gtable_stack <- function(g1, g2){
g1$grobs <- c(g1$grobs, g2$grobs)
g1$layout <- transform(g1$layout, z= z-max(z), name="g2")
g1$layout <- rbind(g1$layout, g2$layout)
g1
}
new_plot <- gtable_stack(g1, new_strips)
grid.newpage()
grid.draw(new_plot)
从this answer借用以下函数,您可以先从虚拟图中提取图例。
# Extract only the legend from "dummy" plot
g_legend <- function(dummy){
tmp <- ggplot_gtable(ggplot_build(dummy))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}
# Assign the legend to a separate object
facet.legend <- g_legend(dummy)
然后您可以使用包 gridExtra
中的 grid.arrange()
...
library(gridExtra)
jpeg("plot-with-facet-legend.jpg", width = 8, height = 6, units = "in", res = 300)
print(grid.arrange(new_plot, facet.legend, nrow = 2, widths = c(7, 1), heights = c(6, 0.01)))
dev.off()
... 生成以下图:
或者:在执行相同的 jpeg(...)
、print(grid.arrange(...))
代码之前,直接从 g2
对象中获取图例的更紧凑的解决方案:
facet.legend <- g2$grobs[[which(sapply(g2$grobs, function(x) x$name) %in% "guide-box")]]
当然,您可以尝试使用 widths
和 heights
参数来生成更整洁的图,并且可能存在另一种解决方案,它比我的更简单一些,但希望如此这至少大致就是您所寻求的。