2009-11-30 16 views
10

Ich fragte gestern this Frage über das Speichern eines Plots in einem Objekt. Ich habe versucht, den ersten Ansatz zu implementieren (bewusst, dass ich nicht angegeben habe, dass ich qplot() in meiner ursprünglichen Frage verwendet) und bemerkte, dass es nicht wie erwartet funktioniert hat.Speichern von Plot-Objekten in einer Liste

library(ggplot2)    # add ggplot2 

string = "C:/example.pdf"  # Setup pdf 
pdf(string,height=6,width=9) 

x_range <- range(1,50)   # Specify Range 

# Create a list to hold the plot objects. 
pltList <- list() 
pltList[] 

for(i in 1 : 16){ 

# Organise data 
y = (1:50) * i * 1000      # Get y col 
x = (1:50)         # get x col 
y = log(y)         # Use natural log 

# Regression 
lm.0 = lm(formula = y ~ x)     # make linear model 
inter = summary(lm.0)$coefficients[1,1]  # Get intercept 
slop = summary(lm.0)$coefficients[2,1]  # Get slope 

# Make plot name 
pltName <- paste('a', i, sep = '') 

# make plot object  
p <- qplot(
    x, y, 
    xlab = "Radius [km]", 
    ylab = "Services [log]", 
    xlim = x_range, 
    main = paste("Sample",i) 
) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)   

print(p)  

pltList[[pltName]] = p  
} 

# close the PDF file 
dev.off() 

Ich habe in diesem Fall Beispielnummern verwendet, so dass der Code ausgeführt wird, wenn es nur kopiert wird. Ich habe ein paar Stunden damit verbracht, darüber zu rätseln, aber ich kann nicht herausfinden, was falsch läuft. Es schreibt den ersten Satz von PDFs ohne Probleme, also habe ich 16 pdfs mit den richtigen Plots.

Dann, wenn ich dieses Stück Code:

string = "C:/test_tabloid.pdf" 
pdf(string, height = 11, width = 17) 

grid.newpage() 
pushViewport(viewport(layout = grid.layout(3, 3))) 

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

counter = 1 

# Page 1 
for (i in 1:3){  
    for (j in 1:3){  
     pltName <- paste('a', counter, sep = '') 
     print(pltList[[pltName]], vp = vplayout(i,j)) 
     counter = counter + 1 
    } 
} 

dev.off() 

das Ergebnis, das ich bekomme, ist die letzte lineare Modell Linie (abline) auf jedem Graphen, aber die Daten nicht ändern. Wenn ich meine Liste von Plots überprüfe, scheint es, dass sie alle von dem letzten Plot überschrieben werden (mit Ausnahme des Objekts abline). Eine weniger wichtige sekundäre Frage war, wie man eine Multi-Seiten-PDF mit mehreren Plots auf jeder Seite generiert, aber das Hauptziel meines Codes war es, die Plots in einer Liste zu speichern, auf die ich zu einem späteren Zeitpunkt zugreifen konnte.

Antwort

10

Ok, also, wenn Ihr Plotbefehl zu

p <- qplot(data = data.frame(x = x, y = y), 
      x, y, 
      xlab = "Radius [km]", 
      ylab = "Services [log]", 
      xlim = x_range, 
      ylim = c(0,10), 
      main = paste("Sample",i) 
      ) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)   

geändert wird, dann funktioniert alles wie erwartet. Hier ist, was ich vermute, passiert (obwohl Hadley wahrscheinlich Dinge klären könnte). Wenn ggplot2 die Daten "speichert", speichert es einen Datenrahmen und die Namen der Parameter. Also für den Befehl, wie ich es gegeben haben, können Sie

> summary(pltList[["a1"]]) 
data: x, y [50x2] 
mapping: x = x, y = y 
scales: x, y 
faceting: facet_grid(. ~ ., FALSE) 
----------------------------------- 
geom_point: 
stat_identity: 
position_identity: (width = NULL, height = NULL) 

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL) 

jedoch erhalten, wenn Sie nicht über einen data Parameter in qplot angeben, werden alle Variablen erhalten im aktuellen Bereich ausgewertet, weil es kein angebracht ist (lesen : gespeichert) Datenrahmen.

data: [0x0] 
mapping: x = x, y = y 
scales: x, y 
faceting: facet_grid(. ~ ., FALSE) 
----------------------------------- 
geom_point: 
stat_identity: 
position_identity: (width = NULL, height = NULL) 

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL) 

Also, wenn die Handlung zum zweiten Mal um erzeugt wird, anstatt die ursprünglichen Werte verwendet, verwendet sie die aktuellen Werte von x und y.

+0

Danke RCS und Jonathan, das Problem wurde behoben. Ich war mir des Datenarguments nicht bewusst und wusste, wie es zum Speichern der Daten verwendet werden konnte. Ich untersuche gerade diesen Abschnitt des Buches. – womble

1

Für Ihre zweite Frage: Mehrseitiges PDF-Dateien sind einfach - siehe help(pdf):

onefile: logical: if true (the default) allow multiple figures in one 
      file. If false, generate a file with name containing the 
      page number for each page. Defaults to ‘TRUE’. 

Für Ihre wichtigste Frage, die ich nicht verstehe, wenn Sie die Plot Eingänge in einer Liste gespeichert werden sollen für die spätere Verarbeitung oder Plot Ausgänge. Wenn es Letzteres ist, bin ich mir nicht sicher, ob plot() ein Objekt zurückgibt, das Sie speichern und abrufen können.

+0

Ich hatte gehofft, die Plot-Ausgaben zu speichern. Wenn ich die Plot-Eingaben speichere, schließt das die Werte von x und y zu dieser bestimmten Zeit ein? – womble

+0

Natürlich. Speichern Sie einfach alle Funktionsargumente usw. in einer Liste. Das ist sehr Standard. Aber Ihre Annahme des Speicherns von _plot output_ ist nicht. Die Plotergebnisse sind geräteabhängig und höchstwahrscheinlich vom Betriebssystem abhängig. Schreiben Sie einfach in eine Datei, möglicherweise eine Bitmap, und zeigen Sie diese an. Oder schreiben Sie Apps im GUI-Stil. Oder öffne einfach mehrere Plot-Fenster. –

+0

"ggplot" kann jedoch Objekte an Sie zurückgeben. In diesem Fall ist Eduardo Antwort Ihr Schlüssel. –

2

Es gibt einen Fehler in Ihrem Code bezüglich der Listen-Subskribierung.

class(pltList[1]) 
[1] "list" 

pltList [1] ist eine Liste enthält das erste Element pltList: Es sollte

pltList[[pltName]] 

nicht

pltList[pltName] 

Hinweis sein.

class(pltList[[1]]) 
[1] "ggplot" 

pltList [[1]] ist das erste Element von pltList.

+0

Entschuldigung - Ich habe einen Fehler gemacht mit dem, was ich einfügen wollte. Ich habe den Unterschied zwischen den Syntaxen nicht vollständig verstanden und habe ihn bearbeitet, um den Unterschied zu erkennen. Mein Fehler existiert jedoch immer noch, wie ich oben beschrieben habe. – womble

1

Ein anderer Vorschlag in Bezug auf Ihre zweite Frage wäre, Sweave oder Brew zu verwenden, da sie Ihnen vollständige Kontrolle darüber geben, wie Sie Ihre mehrseitige PDF-Datei anzeigen.

Schauen Sie sich at this related question an.

4

Ich denke, Sie sollten das data Argument in qplot verwenden, d. H. Speichern Sie Ihre Vektoren in einem Datenrahmen.

Siehe Hadleys Buch, Abschnitt 4.4:

Die Einschränkung der Daten ist einfach: Es muss ein Datenrahmen sein. Dies ist restriktiv und im Gegensatz zu anderen Grafikpaketen in R. Lattice können Funktionen einen optionalen Datenrahmen verwenden oder Vektoren direkt aus der globalen Umgebung verwenden. ...

Die Daten werden im Plot-Objekt als Kopie und nicht als Referenz gespeichert. Dies hat zwei wichtige Konsequenzen: Wenn sich Ihre Daten ändern, wird die Handlung nicht; und ggplot2-Objekte sind vollständig in sich abgeschlossen, so dass sie save() d auf Platte gespeichert und später geladen (loaded) und geplottet werden können, ohne etwas anderes von dieser Sitzung zu benötigen.

Verwandte Themen