2016-07-29 20 views
-2

Dies ist keine sich wiederholende Frage, obwohl der Titel ähnlich erscheinen mag.Wie plotten Sie mehrere ggplot_gtable Objekte auf mehreren Seiten einer PDF?

Nehmen wir an, ich habe eine Funktion f1(), die einmal ein Objekt der Klasse "gTable, grob, gDesc" plottet. Ich verwende grid.draw(), um das Objekt zu zeichnen. So

wenn wir rufen:

pdf("filename.pdf", height = 10, weight =12) 
f1() 
dev.off() 

Dies wird eine Seite von pdf geben das ist, was ich wollte.

Allerdings, wenn ich will, zwei Grundstücke in einem einzigen pdf durch den Code:

pdf("filename.pdf") 
f1() 
f1() 
dev.off() 

ich erhalte, ist eine einzelne Seite PDF nur mit dem zweiten plot.That ist die erste Handlung wurde von der zweiten überschrieben. Um das zu überwinden, verwende ich grid.newpage(), aber das fügt eine zusätzliche leere Seite in der PDF hinzu. Wie vermeide ich das? Ich kann ein zusätzliches Argument verwenden, um eine neue Seite nur zu erstellen, wenn das Argument gesetzt ist. Aber haben wir andere Möglichkeiten?

Ich habe mit grid.arrange() und auch das Argument onefile in pdf() gespielt, aber nichts hat funktioniert.

Auch wenn ich versuche, diese auf dem R-Plot-Fenster zu plotten, dann überschreibt es auf dem vorhandenen offenen Grafikgerät. Nachdem ich das zweite Mal gezeichnet habe, kann ich den ersten Plot nicht mehr mit dem Zurück-Pfeil anzeigen. back arrow of R plot window

Edit: Probe R-Code, der ein Objekt der Klasse Plots "gTable, grob, gDesc"

xxx <- function(){ 
set.seed(1111) 
dd <- diamonds[sample(1:nrow(diamonds), 1000, replace = TRUE), ] 
dd$color <- sample(letters[1:2], 1000, replace = TRUE) 

p <- ggplot(data = dd, aes(x = cut)) 
p1 <- p + geom_bar(fill = "orange", alpha = 1) + facet_wrap(~color)+ 
      ggtitle("Main title")+scale_y_continuous("frequency", expand = c(0, 0))+ 
      labs(x = "cut", y = "frequency")+ 
      theme(panel.background = element_rect(colour = "white"), 
       axis.text.x = element_text(angle = 45, hjust = 1), 
       panel.grid.major = element_blank(), 
       panel.grid.minor = element_blank(), 
       legend.position = "bottom") 

    p2 <- p + geom_line(aes(y = price), alpha = 0)+ 
      labs(x = "", y = "price")+expand_limits(y = 0) + 
      stat_summary(aes(y = price, group = 1, colour = "mean"), fun.y = "mean", geom = c("point"))+ 
      stat_summary(aes(y = price, group = 1, colour = "mean"), fun.y = "mean", geom = c("line"))+ 
      stat_summary(aes(y = price, group = 1, colour = "median"), fun.y = "median", geom = "point")+ 
      stat_summary(aes(y = price, group = 1, colour = "median"), fun.y = "median", geom = "line")+ 
      scale_colour_manual(name = "" ,breaks = c("mean", "median"), values = c("red", "blue"))+ 
      facet_wrap(~color)+ylab("Exposures")+ 
      theme(panel.background = element_rect(fill = NA, colour = "white"), 
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(), 
        panel.border = element_rect(fill = NA, colour = "grey50"), 
        legend.position = "bottom") 

    xx <- ggplot_build(p1) 
    yy <- ggplot_build(p2) 

    nrow <- length(unique(xx$panel$layout$ROW)) 
    ncol <- length(unique(xx$panel$layout$COL)) 
    npanel <- length(xx$panel$layout$PANEL) 

    g1 <- ggplot_gtable(xx) 
    g2 <- ggplot_gtable(yy) 

    pp <- c(subset(g1$layout, grepl("panel", g1$layout$name), se = t:r)) 
    g <- gtable_add_grob(g1, g2$grobs[grepl("panel", g1$layout$name)], 
         pp$t, pp$l, pp$b, pp$l) 

    func1 <- function(grob){ 
     widths <- grob$widths 
     grob$widths[1] <- widths[3] 
     grob$widths[3] <- widths[1] 
     grob$vp[[1]]$layout$widths[1] <- widths[3] 
     grob$vp[[1]]$layout$widths[3] <- widths[1] 

     grob$children[[1]]$hjust <- 1 - grob$children[[1]]$hjust 
     grob$children[[1]]$vjust <- 1 - grob$children[[1]]$vjust 
     grob$children[[1]]$x <- unit(1, "npc") - grob$children[[1]]$x 
     grob 
    } 


    index <- which(g2$layout$name == "ylab") 
    ylab <- g2$grobs[[index]]    # Extract that grob 
    ylab <- func1(ylab) 
    ylab$children[[1]]$rot <- ylab$children[[1]]$rot + 180 
    g <- gtable_add_cols(g, g2$widths[g2$layout[index, ]$l], pos = max(pp$r)) 
    g <-gtable_add_grob(g,ylab, t = min(pp$t), l = max(pp$r)+1, 
         b = max(pp$b), r = max(pp$r)+1, 
         clip = "off", name = "2ndylab") 

    j = 1 
    k = 0 

    for(i in 1:npanel){ 
    if ((i %% ncol == 0) || (i == npanel)){ 
     k = k + 1 
     # swap the 2nd y-axis label 

    index <- which(g2$layout$name == "axis_l-1") # Which grob 
    yaxis <- g2$grobs[[index]]     # Extract the grob 
    ticks <- yaxis$children[[2]] 
     ticks$widths <- rev(ticks$widths) 
    ticks$grobs <- rev(ticks$grobs) 
    ticks$grobs[[1]]$x <- ticks$grobs[[1]]$x - unit(1, "npc") 
    ticks$grobs[[2]] <- func1(ticks$grobs[[2]]) 
    yaxis$children[[2]] <- ticks 
    if ((k == 1) || ((i == npanel) & (i%%ncol != 0)))#to ensure just once d secondary axisis printed 
     g <- gtable_add_cols(g,g2$widths[g2$layout[index,]$l], max(pp$r[j:i])) 
     g <- gtable_add_grob(g,yaxis,max(pp$t[j:i]),max(pp$r[j:i])+1, max(pp$b[j:i]) 
         , max(pp$r[j:i]) + 1, clip = "off", name = "2ndaxis") 
    j = i + 1 
    } 
} 

pp <- c(subset(g2$layout, name == "guide-box", se = t:r)) 
g <- gtable_add_grob(g, g2$grobs[[which(g2$layout$name == "guide-box")]], t = pp$t, 
        l = pp$r, b = pp$b, r = pp$r) 
grid.draw(g) 
} 

Dies ist eine Beispielfunktion. Also, wenn ich den folgenden Code anrufe:

pdf("zzz.pdf") 
xxx() 
xxx() 
dev.off() 

Nur eine einzelne Seite pdf wird im obigen Fall erstellt. Und wenn Sie einfach anrufen:

Dann im R-Plot-Fenster kann ich nur die zweite Grafik anzeigen. Die Zurück-Pfeiltaste ist deaktiviert, seit das erste Diagramm überschrieben wurde.

+0

'grid.arrange' vom' gridExtra' Paket – shayaa

+0

'grid.newpage()' ist der richtige Ansatz – baptiste

+0

können Sie versuchen, mit 'apply' od 'lapply'? Z.B. 'lapply (Daten, f1)'. Und ein kleines reproduzierbares Beispiel liefern. – Jimbou

Antwort

1

Die Lösung grid.newpage() nach dem ersten Plot zu verwenden ist,

xxx <- function() {gg <- ggplotGrob(ggplot()); grid.draw(gg)} 

pdf("zzz.pdf") 
xxx() 
grid.newpage() 
xxx() 
dev.off() 

enter image description here

Sie können es einfacher finden, die Funktion zu haben, einen grob zurückkehren, anstatt sie zu zeichnen, und einen Druck definieren/zeichnen Methode für eine Liste solcher Objekte angezeigt werden. Siehe gridExtra:::print.arrangelist für eine solche Strategie,

xxx <- function() {gg <- ggplotGrob(ggplot()); gg} 

plots <- marrangeGrob(replicate(3, xxx(), simplify = FALSE), nrow=1, ncol=1) 
pdf("zzz.pdf") 
print(plots) 
dev.off() 

enter image description here

+0

danke dafür. Ich bin mir dessen bewusst. Dies wird meine erste Abfrage lösen, würde aber wissen, wie das zweite Problem gelöst werden kann. Wenn wir die Funktion Base R plot() vergleichen, können wir über die Schaltfläche mit dem Pfeil auf die vorherigen Plots im R-Plot-Fenster zugreifen. Wenn Sie jedoch mit diesem Objekt arbeiten, überschreibt es sich gegenseitig. –

+0

das interaktive Verhalten ist wahrscheinlich geräteabhängig (oder IDE) – baptiste