2017-09-15 79 views
0

在這個可重現的示例網格圖中,3個圖有3個填充顏色,z顯示爲「col」藍色,但在第四個圖中只有1個「col」,所以z顯示爲紅。網格圖的常見圖例

我想只顯示一個常見的圖例(我可以這樣做),但我希望z在所有四個圖中都是藍色的。。有沒有簡單的方法來做到這一點?

enter image description here

#--------------------- 
# Reproducible example 
#--------------------- 
library(tidyverse) 
library(ggplot2) 
library(grid) 
library(gridExtra) 
d0 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d1 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d2 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d3 <- read_csv("x, y, col\na,2,z\nb,2,z\nc,1,z") 
p0 <- ggplot(d0) + geom_col(mapping = aes(x, y, fill = col)) 
p1 <- ggplot(d1) + geom_col(mapping = aes(x, y, fill = col)) 
p2 <- ggplot(d2) + geom_col(mapping = aes(x, y, fill = col)) 
p3 <- ggplot(d3) + geom_col(mapping = aes(x, y, fill = col)) 
grid.arrange(p0, arrangeGrob(p1,p2,p3, ncol=3), ncol=1) 

回答

1

這可以通過使用gtable提取傳說和扭轉col因子水平來實現:

library(tidyverse) 
library(ggplot2) 
library(grid) 
library(gridExtra) 
library(gtable) 
d0 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d1 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d2 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d3 <- read_csv("x, y, col\na,2,z\nb,2,z\nc,1,z") 

d0 %>% 
    mutate(col = factor(col, levels = c("z", "y", "x"))) %>% 
    ggplot() + geom_col(mapping = aes(x, y, fill = col)) -> p0 

d1 %>% 
    mutate(col = factor(col, levels = c("z", "y", "x"))) %>% 
    ggplot() + geom_col(mapping = aes(x, y, fill = col))+ 
    theme(legend.position="bottom") -> p1 

d2 %>% 
    mutate(col = factor(col, levels = c("z", "y", "x"))) %>% 
    ggplot() + geom_col(mapping = aes(x, y, fill = col)) -> p2 

d3 %>% 
    ggplot() + geom_col(mapping = aes(x, y, fill = col)) -> p3 

legend = gtable_filter(ggplot_gtable(ggplot_build(p1)), "guide-box") 

grid.arrange(p0 + theme(legend.position="none"), 
      arrangeGrob(p1 + theme(legend.position="none"), 
         p2 + theme(legend.position="none"), 
         p3 + theme(legend.position="none"), 
         nrow = 1), 
      legend, 
      heights=c(1.1, 1.1, 0.1), 
      nrow = 3) 

enter image description here

另一種方法是在每一個使用scale_fill_manual繪製而不改變因素水平。

例如:

p0 + scale_fill_manual(values = c("x" = "red", "z" = "black", "y" = "green")) 

enter image description here

所以用你的原始數據和傳說中提取:

d0 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d1 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d2 <- read_csv("x, y, col\na,2,x\nb,2,y\nc,1,z") 
d3 <- read_csv("x, y, col\na,2,z\nb,2,z\nc,1,z") 
p0 <- ggplot(d0) + geom_col(mapping = aes(x, y, fill = col)) 
p1 <- ggplot(d1) + geom_col(mapping = aes(x, y, fill = col)) 
p2 <- ggplot(d2) + geom_col(mapping = aes(x, y, fill = col)) 
p3 <- ggplot(d3) + geom_col(mapping = aes(x, y, fill = col)) 
legend = gtable_filter(ggplot_gtable(ggplot_build(p1 + theme(legend.position="bottom"))), "guide-box") 

grid.arrange(p0 + theme(legend.position="none"), 
      arrangeGrob(p1 + theme(legend.position="none"), 
         p2 + theme(legend.position="none"), 
         p3 + theme(legend.position="none") + 
          scale_fill_manual(values = c("z" = "#619CFF")), 
         nrow = 1), 
      legend, 
      heights=c(1.1, 1.1, 0.1), 
      nrow = 3) 

enter image description here

+0

謝謝你的偉大的想法。目前,我已經用scale_fill_manual去了,因爲我的代碼像例子一樣只有3個圖例值。我會在有更多時間的情況下探索另一種選擇。 – Carl

1

最後一次爲我GGPLOT2包大放異彩!

使用grid_arrange_shared_legend這是納入包lemonhttps://cran.r-project.org/package=lemon)。在Working with legends小插曲中有一個例子。

結果可能是這樣的: Example from vignette

。但它並沒有爲你的榜樣工作,所以我已經更新包。你需要從GitHub安裝devel的版本:

library(devtools) 
install_github('stefanedwards/lemon', ref='e05337a') 

這將使您以下

library(lemon) 
# your code to create p0 - p4 
nt <- theme(legend.position='none') 
grid_arrange_shared_legend(p0, arrangeGrob(p1+nt,p2+nt,p3+nt, ncol=3), ncol=1, nrow=2) 

enter image description here

+0

謝謝。這個軟件包看起來很有趣,當我有更多時間時,我會試一試。作爲我的示例的短期解決方案,我使用了scale_fill_manual。 – Carl