San*_*att 31
可以通过从图中提取单独的图例,然后在相关图中排列图例来完成.这里的代码使用gtable包中的函数进行提取,然后从gridExtra包中进行函数排列.目的是绘制包含颜色图例和尺寸图例的图表.首先,从仅包含颜色图例的图中提取颜色图例.其次,从仅包含尺寸图例的图表中提取尺寸图例.第三,绘制一个不包含图例的情节.第四,将情节和两个传说安排在一个新的情节中.
# Some data
df <- data.frame(
x = 1:10,
y = 1:10,
colour = factor(sample(1:3, 10, replace = TRUE)),
size = factor(sample(1:3, 10, replace = TRUE)))
library(ggplot2)
library(gridExtra)
library(gtable)
library(grid)
### Step 1
# Draw a plot with the colour legend
(p1 <- ggplot(data = df, aes(x=x, y=y)) +
geom_point(aes(colour = colour)) +
theme_bw() +
theme(legend.position = "top"))
# Extract the colour legend - leg1
leg1 <- gtable_filter(ggplot_gtable(ggplot_build(p1)), "guide-box")
### Step 2
# Draw a plot with the size legend
(p2 <- ggplot(data = df, aes(x=x, y=y)) +
geom_point(aes(size = size)) +
theme_bw())
# Extract the size legend - leg2
leg2 <- gtable_filter(ggplot_gtable(ggplot_build(p2)), "guide-box")
# Step 3
# Draw a plot with no legends - plot
(plot <- ggplot(data = df, aes(x=x, y=y)) +
geom_point(aes(size = size, colour = colour)) +
theme_bw() +
theme(legend.position = "none"))
### Step 4
# Arrange the three components (plot, leg1, leg2)
# The two legends are positioned outside the plot:
# one at the top and the other to the side.
plotNew <- arrangeGrob(leg1, plot,
heights = unit.c(leg1$height, unit(1, "npc") - leg1$height), ncol = 1)
plotNew <- arrangeGrob(plotNew, leg2,
widths = unit.c(unit(1, "npc") - leg2$width, leg2$width), nrow = 1)
grid.newpage()
grid.draw(plotNew)
# OR, arrange one legend at the top and the other inside the plot.
plotNew <- plot +
annotation_custom(grob = leg2, xmin = 7, xmax = 10, ymin = 0, ymax = 4)
plotNew <- arrangeGrob(leg1, plotNew,
heights = unit.c(leg1$height, unit(1, "npc") - leg1$height), ncol = 1)
grid.newpage()
grid.draw(plotNew)
Run Code Online (Sandbox Code Playgroud)

这是使用ggplot2and cowplot(= ggplot2扩展)包的另一种解决方案.
该方法类似于Sandys,因为它将图例作为单独的对象取出,并允许您单独进行放置.它主要设计用于多个图例,这些图例属于图形网格中的两个或多个图.
plot_grid()使用herby 的函数取自这个答案.
这个想法如下:
它似乎有点复杂,时间/代码消耗但是设置一次,你可以适应并用于各种情节/图例定制.
Run Code Online (Sandbox Code Playgroud)library(ggplot2) library(cowplot) # Some data df <- data.frame( Name = factor(rep(c("A", "B", "C"), 12)), Month = factor(rep(1:12, each = 3)), Temp = sample(0:40, 12), Precip = sample(50:400, 12) ) # 1. create plot1 plot1 <- ggplot(df, aes(Month, Temp, fill = Name)) + geom_point( show.legend = F, aes(group = Name, colour = Name), size = 3, shape = 17 ) + geom_smooth( method = "loess", se = F, aes(group = Name, colour = Name), show.legend = F, size = 0.5, linetype = "dashed" ) # 2. create plot2 plot2 <- ggplot(df, aes(Month, Precip, fill = Name)) + geom_bar(stat = "identity", position = "dodge", show.legend = F) + geom_smooth( method = "loess", se = F, aes(group = Name, colour = Name), show.legend = F, size = 1, linetype = "dashed" ) + scale_fill_grey() # 3.1 create legend1 legend1 <- ggplot(df, aes(Month, Temp)) + geom_point( show.legend = T, aes(group = Name, colour = Name), size = 3, shape = 17 ) + geom_smooth( method = "loess", se = F, aes(group = Name, colour = Name), show.legend = T, size = 0.5, linetype = "dashed" ) + labs(colour = "Station") + theme( legend.text = element_text(size = 8), legend.title = element_text( face = "italic", angle = -0, size = 10 ) ) # 3.2 create legend2 legend2 <- ggplot(df, aes(Month, Precip, fill = Name)) + geom_bar(stat = "identity", position = "dodge", show.legend = T) + scale_fill_grey() + guides( fill = guide_legend( title = "", title.theme = element_text( face = "italic", angle = -0, size = 10 ) ) ) + theme(legend.text = element_text(size = 8)) # 3.3 extract "legends only" from ggplot object legend1 <- get_legend(legend1) legend2 <- get_legend(legend2) # 4.1 setup legends grid legend1_grid <- cowplot::plot_grid(legend1, align = "v", nrow = 2) # 4.2 add second legend to grid, specifying its location legends <- legend1_grid + ggplot2::annotation_custom( grob = legend2, xmin = 0.5, xmax = 0.5, ymin = 0.55, ymax = 0.55 ) # 5. plot "plots" + "legends" (with legends in between plots) cowplot::plot_grid(plot1, legends, plot2, ncol = 3, rel_widths = c(0.45, 0.1, 0.45) )
例子:
例子http://i65.tinypic.com/jl1lef.png
更改最终ggplot2调用的顺序会将图例移动到右侧:
cowplot::plot_grid(plot1, plot2, legends, ncol = 3,
rel_widths = c(0.45, 0.45, 0.1))
Run Code Online (Sandbox Code Playgroud)
例2 http://i68.tinypic.com/314yn9i.png
根据我的理解,基本上对ggplot2. 这是哈德利书中的一段话(第 111 页):
ggplot2 尝试使用尽可能少的图例来准确传达情节中使用的美学。如果一个变量用于不止一种美学,它会通过组合图例来实现这一点。图 6.14 显示了点几何的一个例子:如果颜色和形状都映射到同一个变量,那么只需要一个图例。为了合并图例,它们必须具有相同的名称(相同的图例标题)。因此,如果您更改合并图例之一的名称,则需要为所有图例更改名称。