这是使用ggplot 布局和gtable 的一种方法。它从布局中提取颜色图例,在每个键周围绘制框,重新组合图例,然后将图例插入回 ggplot 布局中。
library(ggplot2)
library(gtable)
library(grid)
x<-1:6;
y<-factor(2:7);
z<-1:6;
df <- data.frame(x,y,z)
p = ggplot(df, aes(x,y)) +
geom_point(aes(colour=y, size = z) )
# get ggplot grob
gt = ggplotGrob(p)
# Get the combined legend
leg = gtable_filter(gt, "guide-box")
# The legend has two parts.
# Get the second part - the color legend
leg2 = leg$grobs[[1]]$grobs[[2]]
# Get the locations of the top of each box containing the legend keys
# in this legend's layout
rects <- leg2$layout$t[grepl("bg", leg2$layout$name)]
# Draw boxes around each key
for(i in rects) leg2 = gtable_add_grob(leg2, grid.rect(gp = gpar(col = '#bdbdbd', fill = NA)), t = i, l = 2)
# Insert new color legend back into the combined legend
leg$grobs[[1]]$grobs[2][[1]] <- leg2
# Insert combined legend back into ggplot grob
gt$grobs[gt$layout$name == "guide-box"][[1]] <- leg
# Draw it
grid.newpage()
grid.draw(gt)
这是第二种方法(基于@Baptiste 的answer here),它绘制两个图:一个包含尺寸图例,另一个包含颜色图例(键周围有框)。然后它从每个绘图的布局中提取图例,将两个图例组合成一个图例,然后将组合图例插入回其中一个布局中。
library(ggplot2)
library(gtable)
library(grid)
x<-1:6;
y<-factor(2:7);
z<-1:6;
df <- data.frame(x,y,z)
p1 = ggplot(df, aes(x,y)) +
geom_point(aes(colour=y, size = z) ) +
scale_colour_discrete(guide = "none")
p2 = ggplot(df, aes(x,y)) +
geom_point(aes(colour=y, size = z) ) +
scale_size(guide = "none") +
theme(legend.key = element_rect(colour = '#bdbdbd', size = 0.6))
# Get ggplot grobs
gt1 = ggplotGrob(p1)
gt2 = ggplotGrob(p2)
# Get the legends
leg1 = gtable_filter(gt1, "guide-box")
leg2 = gtable_filter(gt2, "guide-box")
# Combine the legends
leg <- rbind(leg1[["grobs"]][[1]], leg2[["grobs"]][[1]], size = "first")
# Insert legend into g1 (or g2)
gt1$grobs[gt1$layout$name == "guide-box"][[1]] <- leg
# Draw it
grid.newpage()
grid.draw(gt1)