2012-02-28 10 views
23

Ho pensato di utilizzare le funzioni par() o layout() per combinare i ggplot. Sarà possibile utilizzare quelle funzioni?Grafico combinato di ggplot2 (Non in un singolo Plot), utilizzando la funzione par() o layout()?

Dire che voglio tracciare ggplot per scatterplot e ggplot per l'istogramma. E voglio combinare i due grafici (NON IN UN SINGOLO PLOT). È applicabile?

L'ho provato con il semplice tracciamento in R, senza utilizzare le funzioni ggplot. E funziona davvero.

Ecco un esempio da Quick-R, Link: http://www.statmethods.net/advgraphs/layout.html

# 4 figures arranged in 2 rows and 2 columns 
attach(mtcars) 
par(mfrow=c(2,2)) 
plot(wt,mpg, main="Scatterplot of wt vs. mpg") 
plot(wt,disp, main="Scatterplot of wt vs disp") 
hist(wt, main="Histogram of wt") 
boxplot(wt, main="Boxplot of wt") 

# One figure in row 1 and two figures in row 2 
attach(mtcars) 
layout(matrix(c(1,1,2,3), 2, 2, byrow = TRUE)) 
hist(wt) 
hist(mpg) 
hist(disp) 

Ma quando provo ad usare ggplot, e combinare la trama, non ottengo un output.

+0

ggplot2 è non una grafica di base, quindi non è possibile combinare ggplot2 e layout o par (mfrow). devi utilizzare, ad es., plot.arrange ecc. in grigliaExtra. Oppure puoi giocare con viewport nel sistema di griglia. – kohske

+0

Dato che hai chiesto qualcosa come 'layout()', probabilmente vorrai qualcosa come 'grid.arrange()' (come menzionato da kohske). [Questo post collegato] (http://stackoverflow.com/questions/7993722/creating-arbitrary-panes-in-ggplot2/7996205#7996205) (e in particolare la risposta di Ben Bolker) ti darà un buon punto di partenza. –

risposta

32
library(ggplot2) 
library(grid) 


vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y) 


plot1 <- qplot(mtcars,x=wt,y=mpg,geom="point",main="Scatterplot of wt vs. mpg") 
plot2 <- qplot(mtcars,x=wt,y=disp,geom="point",main="Scatterplot of wt vs disp") 
plot3 <- qplot(wt,data=mtcars) 
plot4 <- qplot(wt,mpg,data=mtcars,geom="boxplot") 
plot5 <- qplot(wt,data=mtcars) 
plot6 <- qplot(mpg,data=mtcars) 
plot7 <- qplot(disp,data=mtcars) 

# 4 figures arranged in 2 rows and 2 columns 
grid.newpage() 
pushViewport(viewport(layout = grid.layout(2, 2))) 
print(plot1, vp = vplayout(1, 1)) 
print(plot2, vp = vplayout(1, 2)) 
print(plot3, vp = vplayout(2, 1)) 
print(plot4, vp = vplayout(2, 2)) 


# One figure in row 1 and two figures in row 2 
grid.newpage() 
pushViewport(viewport(layout = grid.layout(2, 2))) 
print(plot5, vp = vplayout(1, 1:2)) 
print(plot6, vp = vplayout(2, 1)) 
print(plot7, vp = vplayout(2, 2)) 
+0

Grazie a tutti voi ragazzi, il mio problema è risolto. –

+1

Per Maiasaura, Grazie per la sceneggiatura/codice. Ma ho ricevuto un errore quando stampo plot1 e plot2, che dice "Errore in eval (expr, envir, enclos): oggetto 'wt' non trovato". Tuttavia, l'ho risolto riorganizzando il tuo argomento in plot1 e plot2. plot1 <- qplot (x = wt, y = mpg, data = mtcars, geom = "point", main = "Scatterplot di wt vs. mpg") e plot2 <- qplot (x = wt, y = disp , data = mtcars, geom = "point", main = "Scatterplot of wt vs disp") Grazie ancora per una rapida risposta. –

+0

@Maiasaura Grazie per le grandi risposte. Come posso aggiungere un titolo all'intera griglia come titolo principale. Ho visto l'opzione grid.text ma in una griglia 2 per 4 non arriva bene in alto e in mezzo. –

7

La risposta coinvolge grid.layout opere, ho usato, e ho votato up-esso. Tuttavia, di solito trovo questa soluzione troppo noiosa e soggetta a errori, e sospetto che la maggior parte degli appassionati di ggplot2 che lo fanno regolarmente lo abbiano avvolto in una funzione. Ho trovato molte di queste funzioni di wrapping nelle ricerche precedenti, ma la mia attuale soluzione workhorse è in un grid addon package called gridExtra. Ha argomenti utili, ma l'impostazione di default righe/colonne è spesso quello che si voleva in primo luogo:

library("ggplot2") 
# Generate list of arbitrary ggplots 
plot1 <- qplot(data = mtcars, x=wt, y=mpg, geom="point",main="Scatterplot of wt vs. mpg") 
plot2 <- qplot(data = mtcars, x=wt, y=disp, geom="point",main="Scatterplot of wt vs disp") 
plot3 <- qplot(wt,data=mtcars) 
plot4 <- qplot(wt,mpg,data=mtcars,geom="boxplot") 
plot5 <- qplot(wt,data=mtcars) 
plot6 <- qplot(mpg,data=mtcars) 
plot7 <- qplot(disp,data=mtcars) 
# You might have produced myPlotList using instead lapply, mc.lapply, plyr::dlply, etc 
myPlotList = list(plot1, plot2, plot3, plot4, plot5, plot6, plot7) 
library("gridExtra") 
do.call(grid.arrange, myPlotList) 

Si noti come l'attuale "combinano le mie trame in una grafica" codice era una riga (dopo aver caricato gridExtra) . Si potrebbe sostenere che mettere le trame in una lista era una linea aggiuntiva, ma in realtà avrei potuto in alternativa utilizzata

grid.arrange(plot1, plot2, plot3, plot4, plot5, plot6, plot7) 

Per un piccolo numero di ggplots questo potrebbe essere preferibile. Tuttavia, per n_plots > 4 inizierai a risentirti dovendo nominarli e digitarli tutti.

+0

se si desidera che due colonne, ad esempio, risultino da grid.arrange, cosa dovrebbe contenere la riga finale? Ho provato le variazioni su args = list (ncol = 2) – lawyeR

+4

Ecco il one-liner: 'do.call (grid.arrange, c (myPlotList, list (ncol = 2)))' –

12

Un'utilità che credo meriti più attenzione per questo è ilpacchetto wq (nota la "O" maiuscola). Da allora è stato rimosso dal pacchetto wq, quindi ho inserito il codice qui sotto e l'ho rinominato lay_out in modo che corrisponda al tipico stile ggplot. È come base::layout in quanto le trame possono essere di dimensioni diverse, disposte in righe e colonne. Ogni argomento a lay_out è un elenco di 3 elementi che comprende il grafico, gli indici di riga in cui tracciarlo e gli indici di colonna in cui tracciarlo.

Ad esempio, utilizzando trame di @ Paolo McMurdie,

lay_out(list(plot1, 1, 1), 
     list(plot2, 1, 2), 
     list(plot3, 2, 1), 
     list(plot4, 2, 2), 
     list(plot5, 3, 1:2), 
     list(plot6, 4, 1:2), 
     list(plot7, 1:2, 3)) 

enter image description here

lay_out = function(...) {  
    x <- list(...) 
    n <- max(sapply(x, function(x) max(x[[2]]))) 
    p <- max(sapply(x, function(x) max(x[[3]]))) 
    grid::pushViewport(grid::viewport(layout = grid::grid.layout(n, p)))  

    for (i in seq_len(length(x))) { 
     print(x[[i]][[1]], vp = grid::viewport(layout.pos.row = x[[i]][[2]], 
      layout.pos.col = x[[i]][[3]])) 
    } 
} 

(codice provenienti da una versione precedente del pacchetto wq, dal commit history on the unofficial Github CRAN mirror.)

+0

Mi piacciono molto queste soluzioni. grid.arrange non offre la bella posizione delle trame. – ahs85

+0

@Grego. Il pacchetto wq (qualità dell'acqua) non sembra avere più la funzione layOut(). È corretto? – lawyeR

+1

@lawyeR apparentemente così. Ho aggiunto il codice alla mia risposta. – Gregor

Problemi correlati