2009-11-30 13 views
10

Le pregunté this pregunta ayer sobre el almacenamiento de un trazado dentro de un objeto. Intenté implementar el primer enfoque (consciente de que no especifiqué que estaba usando qplot() en mi pregunta original) y me di cuenta de que no funcionaba como esperaba.Almacenar objetos de trazado en una lista

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() 

He utilizado números de muestra en este caso para que el código se ejecute si se acaba de copiar. Pasé algunas horas desconcertando sobre esto, pero no puedo entender qué está pasando mal. Escribe el primer conjunto de pdfs sin problema, por lo que tengo 16 pdfs con los trazados correctos.

Entonces cuando uso este pedazo de código:

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() 

el resultado que se ve es la última línea modelo lineal (abline) en cada gráfica, pero los datos no cambia. Cuando reviso mi lista de parcelas, parece que todas se sobrescriben con el gráfico más reciente (con la excepción del objeto abline).

Una pregunta secundaria menos importante fue cómo generar un pdf de páginas con varios gráficos en cada página, pero el objetivo principal de mi código era almacenar los gráficos en una lista a la que podía acceder en una fecha posterior.

Respuesta

10

Ok, por lo que si se cambia el comando plot a

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)   

entonces todo funciona como se espera. Esto es lo que sospecho que está sucediendo (aunque Hadley probablemente podría aclarar las cosas). Cuando ggplot2 "guarda" los datos, lo que realmente hace es guardar un marco de datos y los nombres de los parámetros. Así que para el comando como lo he dado, se obtiene

> 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) 

Sin embargo, si no se especifica un parámetro data en qplot, todas las variables se evalúan en el ámbito actual, porque no hay adjunta (lea : guardado) marco de datos.

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) 

Así que cuando se genera la trama de la segunda vez, en lugar de utilizar los valores originales, utiliza los actuales valores de x y y.

+0

Gracias RCS y Jonathan, esto solucionó el problema. No estaba al tanto del argumento de los datos y de cómo se podría usar para almacenar los datos. Estoy examinando esa sección del libro ahora. – womble

1

Para su segunda pregunta: archivos PDF de varias páginas son fáciles - ver 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’. 

Para su pregunta principal, no entiendo si desea almacenar las entradas de la trama en una lista para un procesamiento posterior, o las salidas de diagrama . Si es el último, no estoy seguro de que plot() devuelva un objeto que pueda almacenar y recuperar.

+0

Tenía la esperanza de almacenar las salidas de trazado. Si almaceno las entradas de la trama, ¿eso incluye los valores de x y y en ese momento particular? – womble

+0

Por supuesto. Simplemente almacene todos los argumentos de funciones, etc. en una lista. Eso es muy estándar. Pero su suposición de almacenar _plot output_ no es así. Los resultados de la trama dependen del dispositivo y muy probablemente dependan del sistema operativo. Simplemente escriba en un archivo, posiblemente un mapa de bits, y visualícelo. O escribe aplicaciones de estilo GUI. O simplemente abra varias ventanas de trazado. –

+0

Sin embargo, 'ggplot' puede devolverte objetos. En cuyo caso, la respuesta de Eduardo es tu clave. –

2

Hay un error en su código relacionado con la subscripción de la lista. Debe ser

pltList[[pltName]] 

no

pltList[pltName] 

Nota:

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

pltList [1] es una lista que contiene el primer elemento de pltList.

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

pltList [[1]] es la primera elemento de pltList.

+0

Lo siento, cometí un error con lo que quise pegar. No entendía del todo la diferencia entre las sintaxis y la había estado editando para ver la diferencia. Sin embargo, mi error todavía existe como lo describo arriba. – womble

1

Otra sugerencia con respecto a su segunda pregunta sería utilizar Sweave o Brew, ya que le darán control total sobre cómo visualiza su pdf de varias páginas.

Echa un vistazo at this related question.

4

Creo que debería usar el argumento data en qplot, es decir, almacenar sus vectores en un marco de datos.

Ver el libro de Hadley, Sección 4.4:

La restricción de los datos es simple: debe ser un marco de datos. Esto es restrictivo y, a diferencia de otros paquetes de gráficos en R. Lattice, las funciones pueden tomar un marco de datos opcional o usar vectores directamente del entorno global. ...

Los datos se almacenan en el objeto de trazado como una copia, no como una referencia. Esto tiene dos consecuencias importantes : si sus datos cambian, la trama no lo hará; y los objetos ggplot2 son completamente independientes para que puedan guardarse() d en el disco y luego cargarse() editarse y trazarse sin necesitar nada más de esa sesión.

Cuestiones relacionadas