2015-05-21 15 views
6

Sto provando a creare 3 grafici in cui tutti i pannelli dovrebbero avere la stessa dimensione, quindi ho pensato che la soluzione potesse essere facet_wrap. Il mio problema è che io non voglio lo stesso numero di grafici in ogniaggiungendo grafici vuoti a facet_wrap in ggplot2

df <- data.frame(group=c(1,1,2,2,2,3,3), 
       name=c('a','b','c','d','e','f','g'), 
       x=c(1,2,3,4,5,6,7), 
       y=c(2,3,4,5,6,7,8)) 
ggplot(df, aes(x,y)) + geom_point() + facet_wrap(~ name, ncol=3) 

Il risultato combina i grafici in un ordine sequenziale, ma vorrei raggrupparli dalla mia colonna gruppo.

Così il risultato mi aspetto è

a b _ 
c d e 
f g _ 

Ma quello che ottengo è

a b c 
d e f 
g _ _ 

Qualcuno ha un suggerimento per creare un grafico come questo, forse con l'aggiunta di grafici vuoti? Ho trovato un altro thread Force facet_wrap to fill bottom row... Ma non ho potuto farlo funzionare nel mio caso.

risposta

10

facet_wrap inserisce semplicemente un grafico dopo l'altro e inserisce "interruzioni di riga" dopo il numero appropriato di grafici. Ma c'è anche facet_grid che ti consente di specificare una riga e un indice di colonna. Il tuo indice di riga è group e ora aggiungere un indice di colonna come segue:

cols<-c(a=1,c=1,f=1,b=2,d=2,g=2,e=3) 
df$col <- as.factor(cols[as.character(df$name)]) 

Ora è possibile tracciare la griglia di sfaccettatura con

ggplot(df, aes(x,y)) + geom_point() + facet_grid(group~col) 

Naturalmente, a seconda di cosa il vostro problema è, si dovrà pensare a un modo appropriato per impostare gli indici delle colonne.

Questa è la trama:

enter image description here

Edit:

In risposta al tuo commento e attingendo this answer, ho creato una seconda soluzione. Usa gridExtra e manipola direttamente il ggplot grob. Penso che dia il risultato desiderato, ma nella forma che presento, è "lavoro manuale". Questa soluzione utilizza facet_wrap anziché facet_grid.

In primo luogo, aggiungo un "livelli di supporto place" alla variabile name, che farà in modo che si creano le sfaccettature vuoti e quindi creare la trama:

df$name2 <- factor(df$name,levels=c('a','b','','c','d','e','f','g',' ')) 
p <- ggplot(df, aes(x,y)) + geom_point() + facet_wrap(~name2,ncol=3,drop=FALSE) 

drop=FALSE è ciò che provoca ggplot per disegnare il vuoto sfaccettature. Questa trama differisce dalla mia prima soluzione solo per il modo in cui le faccette sono etichettate. Ora la parte più delicata:

library(gridExtra) 
g <- ggplotGrob(p) 
## remove empty panels 
g$grobs[names(g$grobs) %in% c("panel3", "panel9", "strip_t3", "strip_t9")] <- NULL 
## remove them from the layout 
g$layout <- g$layout[!(g$layout$name %in% c("panel-3", "panel-9", 
              "strip_t-3", "strip_t-9")),] 
## move axis closer to panel 
g$layout[g$layout$name == "axis_b-9", c("t", "b")] = c(9,9) 

Questo fa sostanzialmente quello che dicono i commenti. Se lavori con un altro set di grafici, guarda l'output di names(g$grobs) e g$layout$name per capire quali elementi devono essere rimossi.

Ora è possibile creare la trama con

grid.newpage() 
grid.draw(g) 

enter image description here

Edit 2:

Per le versioni più recenti del ggplot2 la soluzione di cui sopra non funziona. Sfortunatamente, non so con quale versione sia iniziata, ma sicuramente non funziona con la versione 2.2.1.

La parte che deve essere cambiata è la modifica della Grob:

g <- ggplotGrob(p) 
# get the grobs that must be removed 
rm_grobs <- g$layout$name %in% c("panel-1-3", "panel-3-3", "strip-t-3-1", "strip-t-3-3") 
# remove grobs 
g$grobs[rm_grobs] <- NULL 
g$layout <- g$layout[!rm_grobs, ] 
## move axis closer to panel 
g$layout[g$layout$name == "axis-b-3-3", c("t", "b")] = c(14.5, 14.5) 
grid.newpage() 
grid.draw(g) 

Le principali modifiche sono che g$grobs non è più un elenco di nome e che i nomi dei grobs sono cambiate. Nota che i pannelli sono etichettati come "panel-row-col" mentre per le barre grigie è "strip-t-col-row".

enter image description here

+0

c'è un modo per rimuovere le sfaccettature vuote? – drmariod

+0

Non conosco un modo semplice per rimuovere le sfaccettature vuote né ho mai visto una trama con sfaccettature mancanti nella griglia. Quindi, è possibile che non possa essere fatto con 'ggplot', ma forse ci sono soluzioni che usano' grid' o qualcos'altro. Può essere tecnico, però, e non posso aiutarti ... – Stibu

+1

Ho aggiunto una seconda soluzione che potrebbe essere più vicina a ciò che desideri. – Stibu

Problemi correlati