2013-01-09 9 views
10

ho generato una figura che combina ggplot e basi grafici:fanno pannelli con stessi margini quando combinano grafici ggplot e basi

t <- c(1:(24*14)) 
P <- 24 
A <- 10 
y <- A*sin(2*pi*t/P)+20 
#***************************************************************************** 
par(mfrow = c(2,1)) 
plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude") 
aa <- par("mai") 
plot.new() 

require(gridBase) 
vps <- baseViewports() 
pushViewport(vps$figure) 
pushViewport(plotViewport(margins = aa)) ## I use 'aa' to set the margins 
#******************************************************************************* 
require(ggplot2) 
acz <- acf(y, plot = FALSE) 
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() 
grid.draw(ggplotGrob(p)) ## draw the figure 

uso il comando plotViewport e impostare le dimensioni del pannello secondo le dimensioni il primo pannello, ottenuto con il par ("mai"). La figura allegata mostra il risultato. enter image description here Tuttavia, le dimensioni di entrambi i pannelli non corrispondono, vale a dire il secondo pannello sembra essere leggermente più largo del primo. Come posso superare questo senza dover impostare manualmente i margini con

pushViewport(plotViewport(c(4,1.2,0,1.2))) 
+1

Questo è già abbastanza difficile con un solo sistema grafico, figuriamoci due. C'era un pacchetto 'ggextra' con una funzione' align.plots', ma questo è stato deprecato. Vedi https://groups.google.com/forum/?fromgroups=#!topic/ggplot2-dev/4dKg-qA7eZE – Andrie

risposta

6

Questo dovrebbe dare alcuni suggerimenti:

screenshot

library(grid) 
library(ggplot2) 
require(gridBase) 

par(mfrow = c(2,1)) 
plot(1:10) 
a <- par("mai") 
plot.new() 
vps <- baseViewports() 
pushViewport(vps$figure) 

p = qplot(1:10, 1:10) + theme_bw() 
g <- ggplotGrob(p) 

lw = unit(a[2], "inch") - sum(g$widths[1:3]) 

g$widths[[2]] <- as.list(lw + g$widths[[2]]) 
g$widths[[4]] <- as.list(unit(1, "npc") - unit(a[2] + a[4], "inch")) 
g$widths[[5]] <- unit(a[4], "inch") 
grid.draw(g) 

# draw a shaded vertical band to test the alignment 
grid.rect(unit(a[2], "inch"), unit(0, "inch"), 
      unit(1,"npc") - unit(a[2] + a[4], "inch"), 
      unit(2,"npc"), 
      gp=gpar(lty=2, fill="red", alpha=0.1), hjust=0, vjust=0) 

upViewport() 

ma, in realtà, perchè non fare tutto quanto in ggplot2?

+0

grazie per questo. Il motivo principale per cui si desidera combinare ggplot2 e la grafica di base era il pensiero che alcuni grafici basati sulla grafica di base non fossero implementati nella griglia (ad esempio biplot). – KatyB

3

L'idea principale è di premere 2 finestre di viste di base per ottenere le dimensioni del riquadro di stampa. La soluzione non è generale.

Per prima cosa tracciare la mia trama di base

t <- c(1:(24*14)) 
P <- 24 
A <- 10 
y <- A*sin(2*pi*t/P)+20 
#***************************************************************************** 
par(mfrow = c(2,1)) 
plot(t,y,type = "l",xlab = "Time (hours)",ylab = "Amplitude") 
plot.new() 

In secondo luogo ho le dimensioni del pannello trama. vpp verrà utilizzato solo per le dimensioni di grobs ggplot (simile all'idea di baptiste sopra)

require(gridBase) 
vps <- baseViewports() 
vpp <- pushViewport(vps$figure,vps$plot) ## here I add a new viewport 
vpp <- current.viewport() 
upViewport(2) 

ggplot2 trama SAVEC come una tabella grob:

require(ggplot2) 
p <- ggplot(acd, aes(Lag, ACF)) + geom_area(fill = "grey") + 
    geom_hline(yintercept = c(0.05, -0.05), linetype = "dashed") + 
    theme_bw() 
data <- ggplot_build(p) 
gtable <- ggplot_gtable(data) 

cambio le dimensioni dei grobs. (Qui il motivo per cui la soluzione non è generale)

gtable$heights[[2]] <- vpp$height 
gtable$heights[[4]] <- vpp$height 
gtable$widths[[4]] <- vpp$width 

ho tracciare

grid.draw(gtable) 

enter image description here

+0

Credo che dopo un'attenta ispezione i due non saranno esattamente allineati, dato che ggplot centrerà la trama sul viewport e i margini sinistro/destro potrebbero differire. – baptiste

+0

@baptiste Hai ragione. Personalmente non sono soddisfatto della mia soluzione. Quando lo collaudo con altri mar, ad esempio mar (2,1) e mar (2,2) e ho dovuto modificare le dimensioni dei grobs. Ma con la mia soluzione il ** vpp ** ha le giuste dimensioni della trama (l'ho testato con grid.rect), forse puoi usarlo per modificare i groove di ggplot2. – agstudy

Problemi correlati