我有一个数据集的图,在每个图中都有不同的过滤方式。我的目标是获得一个共同的图例,其中包括图表my_hist_z,my_hist_y,my_hist_x上显示的所有因素。
示例:
library(ggplot2); library(gridExtra); library(grid)
z <- subset(diamonds, subset = cut == "Fair" | cut == "Good")
y <- subset(diamonds, subset = cut == "Good")
x <- subset(diamonds, subset = cut == "Premium" | cut == "Fair")
colours = c("Fair" = "#666362",
"Good" = "#D40511",
"Very Good" = "#FFCC00",
"Premium" = "#000000",
"Ideal" = "#BBBBB3")
my_hist_z <-ggplot(z, aes(clarity, fill=cut)) + geom_bar() +
scale_fill_manual(values = colours)
my_hist_y <-ggplot(y, aes(clarity, fill=cut)) + geom_bar() +
scale_fill_manual(values = colours)
my_hist_x <-ggplot(x, aes(clarity, fill=cut)) + geom_bar() +
scale_fill_manual(values = colours)
my_hist<-ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar() +
scale_fill_manual(values = colours)
潜在解决方案: https://andyphilips.github.io/blog/2017/04/04/single-legend-for-multiple-plots.html 仅使用已定义绘图的一个图例,但不会聚合所有涉及的元素。
有什么想法吗?理想情况下,解决方案是动态的,因为这些图被描述为for循环的一部分。 谢谢!
答案 0 :(得分:2)
首先,删除三个图例中除了一个之外的所有图例,并设置段drop = FALSE
library(ggplot2)
library(gridExtra)
library(grid)
z <- subset(diamonds, subset = cut == "Fair" | cut == "Good")
y <- subset(diamonds, subset = cut == "Good")
x <- subset(diamonds, subset = cut == "Premium" | cut == "Fair")
colours = c("Fair" = "#666362",
"Good" = "#D40511",
"Very Good" = "#FFCC00",
"Premium" = "#000000",
"Ideal" = "#BBBBB3")
my_hist_z <-ggplot(z, aes(clarity, fill=cut)) + geom_bar() +
scale_fill_manual(values = colours, drop = FALSE) +
theme(legend.position = "none")
my_hist_y <-ggplot(y, aes(clarity, fill=cut)) + geom_bar() +
scale_fill_manual(values = colours, drop = FALSE) +
theme(legend.position = "none")
my_hist_x <-ggplot(x, aes(clarity, fill=cut)) + geom_bar() +
scale_fill_manual(values = colours, drop = FALSE)
其次,使用上面提到的post中的函数grid_arrange_shared_legend()
来合并所有三个图
grid_arrange_shared_legend <- function(..., ncol = length(list(...)), nrow = 1, position = c("bottom", "right")) {
plots <- list(...)
position <- match.arg(position)
g <- ggplotGrob(plots[[1]] +
theme(legend.position = position))$grobs
legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
lheight <- sum(legend$height)
lwidth <- sum(legend$width)
gl <- lapply(plots, function(x) x +
theme(legend.position = "none"))
gl <- c(gl, ncol = ncol, nrow = nrow)
combined <- switch(position,
"bottom" = arrangeGrob(do.call(arrangeGrob, gl),
legend,ncol = 1,
heights = unit.c(unit(1, "npc") - lheight, lheight)),
"right" = arrangeGrob(do.call(arrangeGrob, gl),
legend, ncol = 2,
widths = unit.c(unit(1, "npc") - lwidth, lwidth)))
grid.newpage()
grid.draw(combined)
# return gtable invisibly
invisible(combined)
}
grid_arrange_shared_legend(my_hist_z,my_hist_y,my_hist_x, ncol = 3)
答案 1 :(得分:1)
这样可行,但不是我要说的最优雅的解决方案:
library(ggplot2)
z <- subset(diamonds, subset = cut == "Fair" | cut == "Good")
y <- subset(diamonds, subset = cut == "Good")
x <- subset(diamonds, subset = cut == "Premium" | cut == "Fair")
colours = c("Fair" = "#666362",
"Good" = "#D40511",
"Very Good" = "#FFCC00",
"Premium" = "#000000",
"Ideal" = "#BBBBB3")
all_levels <- unique(c(levels(factor(x$cut)), levels(factor(y$cut)), levels(factor(z$cut))))
x$cut <- factor(x$cut, levels = all_levels)
y$cut <- factor(y$cut, levels = all_levels)
z$cut <- factor(z$cut, levels = all_levels)
ggplot(z, aes(clarity, fill = cut)) + geom_bar() +
scale_fill_manual(values = colours, drop = F)
修改强>
如果您的所有地块都属于同一类型,则可将它们合并,然后使用facet_wrap
进行绘制:
z$subset <- "z"
y$subset <- "y"
x$subset <- "x"
xyz <- rbind(x, y, z)
ggplot(xyz, aes(clarity, fill = cut)) + geom_bar() +
facet_wrap(~subset) +
scale_fill_manual(values = colours) +
theme(legend.position = "bottom")
您可以通过将strip.text = element_blank()
添加到theme
来隐藏小平面标签。
如果您的情节类型不同,我担心您不得不使用杨的解决方案。