我有一个图,其中有四个由ggplot2
和grid.arrange
组成的面板。每个面板都有一个图例,所有图例都相同。
如何删除图例中的底部的4个图例并创建一个唯一的图例?
这是我的示例数据和图表:
set.seed(100)
df_1 = data.frame(lat = rnorm(20),
lon = rnorm(20),
cor = c(rep('positive', 7), rep('negative', 13)),
sign = c(rep(99, 5), rep(95, 6), rep(90,9)))
lst_df = list(df_1, df_1, df_1, df_1)
library(ggplot2)
library(gridExtra)
library(grid)
for (i in 1:length(lst_df)) {
p[[i]] = ggplot() +
geom_point(data=lst_df[[i]], aes(x=lon, y=lat, size=sign, colour = cor), alpha = 0.5) +
scale_color_manual(values=c("blue", "orange"),
name='col',
labels = c('neg', 'pos'),
guide = guide_legend(override.aes = list(alpha = 1, size = 3))) +
scale_size(range = c(1,3),
breaks = c(90, 95, 99),
labels = c(1, 5, 10),
name = 'test',
guide = guide_legend(override.aes = list(colour = 'black',
alpha = 1)))
}
grid.arrange(p[[1]], p[[2]], p[[3]], p[[4]],
ncol=2, nrow=2,
top=textGrob(expression(bold("test")), gp=gpar(fontsize=25, face= 'bold')))
有什么建议吗? 谢谢
答案 0 :(得分:5)
这是一个带有cowplot
的工作流程,它提供了一些精巧的功能,用于将杂项组合在一起并提取图例等元素。他们有detailed vignette来创建带有共享图例的图网格,就像您正在寻找的图例一样。同样,plot annotations上的装饰图案会越过cowplot
函数来创建和添加标签-它们的功能与其他图元素非常相似,并且可以在cowplot::plot_grid
中使用。
该过程基本上是
lapply
创建一个没有图例的地块列表(可以是循环)顺便说一句,加载cowplot
使其可以设置其默认的ggplot
主题,这不是我特别喜欢的主题,因此我使用cowplot::function
表示法代替了library(cowplot)
。
您可以调整用于制作最终网格的相对高度-这是最适合我的第一个比率。
如果出现的话,几个月前,我发布了一个问题,内容是如何使draw_label
成为主题主题指南,就像您期望的一般ggplot
元素(如标题)那样;软件包作者和我的专业职能部门提供的答案是here。
library(ggplot2)
...
p_no_legend <- lapply(p, function(x) x + theme(legend.position = "none"))
legend <- cowplot::get_legend(p[[1]] + theme(legend.position = "bottom"))
title <- cowplot::ggdraw() + cowplot::draw_label("test", fontface = "bold")
p_grid <- cowplot::plot_grid(plotlist = p_no_legend, ncol = 2)
cowplot::plot_grid(title, p_grid, legend, ncol = 1, rel_heights = c(0.1, 1, 0.2))
由reprex package(v0.2.0)于2018-09-11创建。
答案 1 :(得分:2)
正如卡米尔指出的那样,cowplot
有一个非常简单的方法。您也可以通过手动安排grobs
来做到这一点。如果您的图具有不同的宽度,比例和折点,则效果特别好。 One example here.
除非cowplot
可以这样做,否则手动进行操作的好处是您可以指定哪些图获得x轴标签和y轴标题/标签,因此最后只能有x轴底部网格上的标题/标签,左侧网格上的y轴标题/标签。缺点是,如果有多个绘图,则定义多个绘图功能很麻烦。
df_plots <- lapply(lst_df, function(x) {
ggplot() +
geom_point(data=lst_df[[i]], aes(x=lon, y=lat, size=sign, colour = cor), alpha = 0.5) +
scale_color_manual(values=c("blue", "orange"),
name='col',
labels = c('neg', 'pos'),
guide = guide_legend(override.aes = list(alpha = 1, size = 3))) +
scale_size(range = c(1,3),
breaks = c(90, 95, 99),
labels = c(1, 5, 10),
name = 'test',
guide = guide_legend(override.aes = list(colour = 'black',
alpha = 1)))
})
df_leg <- get_legend(df_plots[[1]]) # get legend
df_plots_noleg <- lapply(lst_df, function(x) { # make plots with no legends, however you want to do this
ggplot() +
geom_point(data=lst_df[[i]], aes(x=lon, y=lat, size=sign, colour = cor), alpha = 0.5) +
scale_color_manual(values=c("blue", "orange"),
name='col',
labels = c('neg', 'pos'),
guide = guide_legend(override.aes = list(alpha = 1, size = 3))) +
theme(legend.position = "none")
})
如果绘图的宽度开始变化,这对于对齐轴很重要。由于在此示例中它们都是相同的,所以没关系。
#maxWidth_df_plots <- grid::unit.pmax(df_plots_noleg1$widths[2:5], df_plots_noleg2$widths[2:5], df_plots_noleg3$widths[2:5], df_plots_noleg4$widths[2:5]) #get your grob widths
#df_plots_noleg1$widths[2:5] <- as.list(maxWidth1Page1)
#df_plots_noleg2$widths[2:5] <- as.list(maxWidth1Page1)
#df_plots_noleg3$widths[2:5] <- as.list(maxWidth1Page1)
#df_plots_noleg4$widths[2:5] <- as.list(maxWidth1Page1)
df_plots1 <- ggplotGrob(df_plots_noleg[[1]])
df_plots2 <- ggplotGrob(df_plots_noleg[[2]])
df_plots3 <- ggplotGrob(df_plots_noleg[[3]])
df_plots4 <- ggplotGrob(df_plots_noleg[[4]])
df_plot_arranged <- grid.arrange(arrangeGrob(df_plots1, df_plots2, df_plots3, df_plots4, nrow = 2),
arrangeGrob(nullGrob(), df_leg, nullGrob(), nrow = 1), ncol = 1, heights = c(4,0.5),
top = textGrob("Title Text Holder Here", gp = gpar(fotsize = 12, font = 2)))
我提到的好处是您可以控制哪些图形获得什么标签。这是控制宽度的地方,如您在图像中看到的,右图比左图宽,顶图比底图高。
df_plots1 <- df_plots_noleg[[1]] + theme(axis.title.x = element_blank(), axis.text.x = element_blank())
df_plots2 <- df_plots_noleg[[2]] + theme(axis.title.x = element_blank(), axis.title.y = element_blank(),
axis.text.x = element_blank(), axis.text.y = element_blank())
df_plots4 <- df_plots_noleg[[4]] + theme(axis.title.y = element_blank(), axis.text.y = element_blank())
df_plots1 <- ggplotGrob(df_plots1)
df_plots2 <- ggplotGrob(df_plots2)
df_plots3 <- ggplotGrob(df_plots_noleg[[3]])
df_plots4 <- ggplotGrob(df_plots4)
df_plot_arranged <- grid.arrange(arrangeGrob(df_plots1, df_plots2, df_plots3, df_plots4, nrow = 2),
arrangeGrob(nullGrob(), df_leg, nullGrob(), nrow = 1), ncol = 1, heights = c(4,0.5),
top = textGrob("Title Text Holder Here", gp = gpar(fotsize = 12, font = 2)))