2017-09-15 2 views
0

Dans cet exemple de graphe reproductible, 3 tracés ont 3 couleurs de remplissage, et z s'affiche avec le "col" bleu, mais dans le quatrième graphe, il n'y a qu'un "col", donc z s'affiche comme rouge.Légende commune pour un graphe de grille

Je veux montrer seulement une légende commune (que je peux faire), mais je veux que z soit bleu dans les quatre graphiques.. Y a-t-il un moyen simple de faire cela?

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) 

Répondre

1

Ceci peut être réalisé en utilisant gtable pour extraire la légende et inverser les niveaux de col facteur:

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

Une autre approche consiste à utiliser scale_fill_manual dans tous les tracer sans changer les niveaux de facteur.

exemple:

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

enter image description here

donc avec vos données originales et légende extrait:

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

Merci pour les grandes idées. Pour l'instant, je suis passé avec scale_fill_manual car mon code, comme l'exemple, n'a que 3 valeurs de légende. Je vais explorer l'autre option quand j'ai plus de temps. – Carl

1

Enfin un temps pour mon forfait ggplot2 de briller!

Utiliser grid_arrange_shared_legend qui a été incorporé dans le paquet lemon (https://cran.r-project.org/package=lemon). Il y a un exemple dans la vignette Working with legends.

Le résultat pourrait ressembler à ceci: Example from vignette

Mais ... il ne fonctionne pas pour votre exemple, je l'ai mis à jour le paquet. Vous devez installer le devel version de github:

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

qui vous donnera les éléments suivants

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

Merci. Ce paquet a l'air intéressant, et je vais essayer quand j'ai plus de temps. Comme une solution à court terme pour l'exemple que j'ai, j'ai utilisé scale_fill_manual. – Carl