Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing plot objects in a list

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.

like image 631
womble Avatar asked Nov 30 '09 15:11

womble


People also ask

Can you make a list of plots in R?

List of plots using map() function in purrr. Using the results from split() function, we can create a list of plots, ggplot objects, using map() function in purrr R package. In this example, map() makes a scatter plot for each species.

How do I save a list in Ggplots?

You can either print directly a ggplot into PNG/PDF files or use the convenient function ggsave() for saving a ggplot. The default of ggsave() is to export the last plot that you displayed, using the size of the current graphics device. It also guesses the type of graphics device from the extension.

What package is Multiplot in R?

multiplot is an easy to use function to put multiple graphs on the same page using R statistical software and ggplot2 plotting methods. This function is from easyGgplot2 package.


1 Answers

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.

like image 109
Jonathan Chang Avatar answered Oct 07 '22 10:10

Jonathan Chang