Storing plot objects in a list
ggplot2, pdf, plot, r, statistics
Solution
Ok, so if your plot command is changed to
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)
then everything works as expected. Here's what I suspect is happening (although Hadley could probably clarify things). When ggplot2 "saves" the data, what it actually does is save a data frame, and the names of the parameters. So for the command as I have given it, you get
> 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)
However, if you don't specify a `data` parameter in qplot, all the variables get evaluated in the current scope, because there is no attached (read: saved) data frame.
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)
So when the plot is generated the second time around, rather than using the original values, it uses the current values of `x` and `y`.
Problem
I asked this question yesterday about storing a plot within an object. I tried implementing the first approach (aware that I did not specify that I was using `qplot()` in my original question) and noticed that it did not work as expected. ``` 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() ``` I have used sample numbers in this case so the code runs if it is just copied. I did spend a few hours puzzling over this but I cannot figure out what is going wrong. It writes the first set of pdfs without problem, so I have 16 pdfs with the correct plots. Then when I use this piece of 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() ``` the result I get is the last linear model line (`abline`) on every graph, but the data does not change. When I check my list of plots, it seems that all of them become overwritten by the most recent plot (with the exception of the `abline` object). A less important secondary question was how to generate a muli-page pdf with several plots on each page, but the main goal of my code was to store the plots in a list that I could access at a later date.