2013-01-02 9 views
59

Vorrei generare una figura che abbia una combinazione di grafica di base e ggplot. Il codice seguente mostra la mia figura utilizzando la base di funzioni di R tracciato:Combina grafica di base e ggplot nella finestra di figura R

t <- c(1:(24*14)) 
P <- 24 
A <- 10 
y <- A*sin(2*pi*t/P)+20 

par(mfrow=c(2,2)) 
plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude",main = "Time series") 
acf(y,main = "Autocorrelation",xlab = "Lag (hours)", ylab = "ACF") 
spectrum(y,method = "ar",main = "Spectral density function", 
     xlab = "Frequency (cycles per hour)",ylab = "Spectrum") 
require(biwavelet) 
t1 <- cbind(t, y) 
wt.t1=wt(t1) 
plot(wt.t1, plot.cb=FALSE, plot.phase=FALSE,main = "Continuous wavelet transform", 
    ylab = "Period (hours)",xlab = "Time (hours)") 

che genera enter image description here

La maggior parte di questi pannelli sembrano sufficienti per me per includere nel mio rapporto. Tuttavia, la trama che mostra l'autocorrelazione deve essere migliorata. Questo sembra molto meglio utilizzando ggplot:

require(ggplot2) 
acz <- acf(y, plot=F) 
acd <- data.frame(lag=acz$lag, acf=acz$acf) 
ggplot(acd, aes(lag, acf)) + geom_area(fill="grey") + 
    geom_hline(yintercept=c(0.05, -0.05), linetype="dashed") + 
    theme_bw() 

enter image description here

Tuttavia, visto che ggplot non è un grafico di base, non possiamo combinare ggplot con layout o pari (mfrow). Come posso sostituire il grafico di autocorrelazione generato dalla grafica di base con quello generato da ggplot? So che posso usare grid.arrange se tutte le mie figure sono state create con ggplot, ma come faccio se solo uno dei grafici viene generato in ggplot?

+3

potrebbe essere quasi facile, e guardare più consistente, per usare 'polygon' con l'uscita di' ACF() 'per costruire una trama di base grafica che ricorda il' ggplot' uno. –

+0

Grazie per la nostra risposta. Questa domanda è davvero finalizzata a imparare come combinare ggplot e grafica di base in una finestra di figura, mi rendo conto che potrebbero esserci modi più efficienti per generare la figura mostrata, ma per gli scopi futuri vorrei imparare il metodo specificato. – KatyB

+3

controlla il pacchetto 'gridBase' ... –

risposta

47

Utilizzando il pacchetto gridBase, è possibile farlo semplicemente aggiungendo 2 righe. Penso che se vuoi fare una trama divertente con la griglia devi solo capire e padroneggiare le finestre . È davvero l'oggetto base del pacchetto della griglia.

vps <- baseViewports() 
pushViewport(vps$figure) ## I am in the space of the autocorrelation plot 

La funzione baseViewports() restituisce un elenco di tre finestre di griglia. Io uso qui la figura Viewport Un viewport corrispondente alla regione di figura della trama corrente corrente.

Ecco come appare la soluzione finale:

enter image description here

library(gridBase) 
par(mfrow=c(2, 2)) 
plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude",main = "Time series") 
plot(wt.t1, plot.cb=FALSE, plot.phase=FALSE,main = "Continuous wavelet transform", 
    ylab = "Period (hours)",xlab = "Time (hours)") 
spectrum(y,method = "ar",main = "Spectral density function", 
     xlab = "Frequency (cycles per hour)",ylab = "Spectrum") 
## the last one is the current plot 
plot.new()    ## suggested by @Josh 
vps <- baseViewports() 
pushViewport(vps$figure) ## I am in the space of the autocorrelation plot 
vp1 <-plotViewport(c(1.8,1,0,1)) ## create new vp with margins, you play with this values 
require(ggplot2) 
acz <- acf(y, plot=F) 
acd <- data.frame(lag=acz$lag, acf=acz$acf) 
p <- ggplot(acd, aes(lag, acf)) + geom_area(fill="grey") + 
    geom_hline(yintercept=c(0.05, -0.05), linetype="dashed") + 
    theme_bw()+labs(title= "Autocorrelation\n")+ 
    ## some setting in the title to get something near to the other plots 
    theme(plot.title = element_text(size = rel(1.4),face ='bold')) 
print(p,vp = vp1)  ## suggested by @bpatiste 
+0

Sì, ho provato questo, il problema con questo è che la trama generata con ggplot è molto più grande rispetto agli altri pannelli (come potete vedere sopra). C'è un metodo per cambiare questo? – KatyB

+0

@Kate I upadte la mia risposta. – agstudy

+0

+1 Molto bello. Se hai sostituito la chiamata a 'acf (...)' con una chiamata a 'trama.new() ', eviterai di dover chiamare' grid.rect() 'a 'white-out' la trama acf. –

10

È possibile utilizzare il comando di stampa con un Grob e viewport.
Prima trama grafica di base quindi aggiungere il ggplot

library(grid) 

# Let's say that P is your plot 
P <- ggplot(acd, # etc...) 

# create an apporpriate viewport. Modify the dimensions and coordinates as needed 
vp.BottomRight <- viewport(height=unit(.5, "npc"), width=unit(0.5, "npc"), 
          just=c("left","top"), 
          y=0.5, x=0.5) 

# plot your base graphics 
par(mfrow=c(2,2)) 
plot(y,type #etc ....) 

# plot the ggplot using the print command 
print(P, vp=vp.BottomRight) 
+0

Ciao Ricardo. Sai come controllare le larghezze delle trame con il tuo metodo? Ad esempio voglio un grafico di base e un grafico ggplot2 affiancati, ma con una larghezza maggiore per il grafico di base. –

+0

Ciao Stéphane, puoi farlo regolando le impostazioni nella riga 'viewport()'. Nello specifico, dovresti regolare il valore di 'width' e' y', sperimentando valori diversi fino ad ottenere i risultati desiderati. –

+0

Grazie, Ricardo. In realtà ho aperto una domanda qui http://stackoverflow.com/questions/14358526/controlling-column-widths-for-side-by-side-base-graphic-and-ggplot2-graphic/14358752 –

5

Io sono un fan del pacchetto gridGraphics. Per qualche motivo ho avuto problemi con gridBase.

library(ggplot2) 
library(gridGraphics) 
data.frame(x = 2:10, y = 12:20) -> dat 
plot(dat$x, dat$y) 
grid.echo() 
grid.grab() -> mapgrob 
ggplot(data = dat) + geom_point(aes(x = x, y = y)) 
pushViewport(viewport(x = .8, y = .4, height = .2, width = .2))  
grid.draw(mapgrob) 

enter image description here