I'd like to spawn several graphics windows from within a function in R using ggplot graphics...
testf <- function(a, b) {
devAskNewPage(TRUE)
qplot(a, b);
# grid.newpage(recording = TRUE)
dev.new()
qplot(a, a+a);
# grid.newpage(recording = TRUE)
dev.new()
qplot(b, b+b);
}
library(ggplot2)
x <- rnorm(50)
y <- rnorm(50)
testf(x, y)
However, neither dev.new() nor grid.newpage() seems to flush the preceding plot.
I know that, in R, functions normally only produce the last thing they evaluate, but I'd like to understand the process better and to learn of any possible workarounds.
Thoughts?
The grid-based graphics functions in lattice and ggplot2 create a graph object, but do not display it. The print() method for the graph object produces the actual display, i.e.,
print(qplot(x, y))
solves the problem.
See R FAQ 7.22.
Related
I started using the lattice graphic package but I stumbled into a problem. I hope somebody can help me out.
I want to plot a histogram using the corresponding function.
Here is the file foo.r:
library("lattice")
data <- data.frame(c(1:2),c(2:3))
colnames(data) <- c("RT", "Type")
pdf("/tmp/baz.pdf")
histogram( ~ RT | factor(Type), data = data)
dev.off()
When I run this code using R --vanilla < foo.r it works all fine.
However, if I use a second file bar.r with
source("bar")
and run R --vanilla < bar.r the code produces an erroneous pdf file.
Now I found out that source("bar", echo=TRUE) solves the problem. What is going on here? Is this a bug or am I missing something?
I'm using R version 2.13.1 (2011-07-08) with lattice_0.19-30
It is in the FAQ for R -- you need print() around the lattice function you call:
7.22 Why do lattice/trellis graphics not work?
The most likely reason is that you forgot to tell R to display the
graph. Lattice functions such as xyplot() create a graph object, but
do not display it (the same is true of ggplot2 graphics, and Trellis
graphics in S-Plus). The print() method for the graph object produces
the actual display. When you use these functions interactively at the
command line, the result is automatically printed, but in source() or
inside your own functions you will need an explicit print() statement.
Example of the case
visualise.r
calls plot2this.r
calls ggplot2 and returns p object
Here the fix in the function plot2this.r from return(p) to return(print(p)).
Initial plot2this.r
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(p)
Fix
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(print(p))
Output now: expected output with the wanted plot.
I started using the lattice graphic package but I stumbled into a problem. I hope somebody can help me out.
I want to plot a histogram using the corresponding function.
Here is the file foo.r:
library("lattice")
data <- data.frame(c(1:2),c(2:3))
colnames(data) <- c("RT", "Type")
pdf("/tmp/baz.pdf")
histogram( ~ RT | factor(Type), data = data)
dev.off()
When I run this code using R --vanilla < foo.r it works all fine.
However, if I use a second file bar.r with
source("bar")
and run R --vanilla < bar.r the code produces an erroneous pdf file.
Now I found out that source("bar", echo=TRUE) solves the problem. What is going on here? Is this a bug or am I missing something?
I'm using R version 2.13.1 (2011-07-08) with lattice_0.19-30
It is in the FAQ for R -- you need print() around the lattice function you call:
7.22 Why do lattice/trellis graphics not work?
The most likely reason is that you forgot to tell R to display the
graph. Lattice functions such as xyplot() create a graph object, but
do not display it (the same is true of ggplot2 graphics, and Trellis
graphics in S-Plus). The print() method for the graph object produces
the actual display. When you use these functions interactively at the
command line, the result is automatically printed, but in source() or
inside your own functions you will need an explicit print() statement.
Example of the case
visualise.r
calls plot2this.r
calls ggplot2 and returns p object
Here the fix in the function plot2this.r from return(p) to return(print(p)).
Initial plot2this.r
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(p)
Fix
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(print(p))
Output now: expected output with the wanted plot.
I'd like to spawn several graphics windows from within a function in R using ggplot graphics...
testf <- function(a, b) {
devAskNewPage(TRUE)
qplot(a, b);
# grid.newpage(recording = TRUE)
dev.new()
qplot(a, a+a);
# grid.newpage(recording = TRUE)
dev.new()
qplot(b, b+b);
}
library(ggplot2)
x <- rnorm(50)
y <- rnorm(50)
testf(x, y)
However, neither dev.new() nor grid.newpage() seems to flush the preceding plot.
I know that, in R, functions normally only produce the last thing they evaluate, but I'd like to understand the process better and to learn of any possible workarounds.
Thoughts?
The grid-based graphics functions in lattice and ggplot2 create a graph object, but do not display it. The print() method for the graph object produces the actual display, i.e.,
print(qplot(x, y))
solves the problem.
See R FAQ 7.22.
How to get graph for each column of data.frame within one plot with loop? Must be easy just can't figure it out.
Sample data:
rdata <- data.frame(y=rnorm(1000,2,2),v1=rnorm(1000,1,1),v2=rnorm(1000,3,3),
v3=rnorm(1000,4,4),v4=rnorm(1000,5,5))
What I have tried?
library(lattice)
p <- par(mfrow=c(2,2))
for(i in 2:5){
w <- xyplot(y~rdata[,i],rdata)
print(w)
}
par(p)
If you don't have to use lattice you can just use base plot instead and it should work as you want.
p <- par(mfrow=c(2,2))
for(i in 2:5){
plot(y~rdata[,i],rdata)
}
par(p)
If you want to use lattice look this answer. Lattice ignores par, so you have to do some more work to achieve what you want.
Inorder to easily arrange a bunch of lattice plots, I like to use the helper function print.plotlist. It has a layout= parameter that acts like the layout() function for base graphics. For example, you could call
rdata <- data.frame(y=rnorm(1000,2,2),v1=rnorm(1000,1,1),v2=rnorm(1000,3,3),
v3=rnorm(1000,4,4),v4=rnorm(1000,5,5))
library(lattice)
plots<-lapply(2:5, function(i) {xyplot(y~rdata[,i],rdata)})
print.plotlist(plots, layout=matrix(1:4, ncol=2))
to get
Otherwise you normally use a split= parameter to the print statement to place a plot in a subsection of the device. For example, you could also do
print(plots[[1]], split=c(1,1,2,2), more=T)
print(plots[[2]], split=c(1,2,2,2), more=T)
print(plots[[3]], split=c(2,1,2,2), more=T)
print(plots[[4]], split=c(2,2,2,2))
I have written a function that draws some plots, and returns a list, similar in style to the following format:
myfun <- function(x, y){
plot(x, y)
points(x+1, y+1)
abline(v=x[1])
mylist <- list(x=x,y=y,line=x[1])
return(mylist)
}
This works fine. However, in R, one generally plots from functions in the following way:
x <- rnorm(100)
y <- rnorm(100)
lin <- lm(x~y)
plot(lin)
i.e., one creates an object using the function, then uses plot(object) to get the plot. How can I set up my function to behave in this way? I've had a look at a few guides to writing R packages (including hadley's), but I couldn't find reference to this problem.
I would like to create this functionality so I can upload what I've created to CRAN or R-Forge.
You could create your own S3 class for it (
R provides a lot of object oriented systems (S3, S4, R5, R.oo, ...), see also: http://adv-r.had.co.nz/OO-essentials.html):
# create an object with an own class
lin = list(x=rnorm(100), y=rnorm(100))
class(lin) = "mylin"
# overload plotting function
plot.mylin = function(l) {
plot(l$x, l$y)
points(l$x+1, l$y+1, col=2)
abline(v=l$x[1])
}
# run it
plot(lin)