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))
Related
I have created one function that contains two types of plots and it will give you one image. However, the title of this image will change depending on one list, so, you will have several plots but different title.
(The original function will change the numbers that the plot uses but, in essence, is what I need).
This is the example that I have created.
list_genes <- c("GEN1", "GEN2", "GEN3")
myfunction <- function(x,y){
for(gene in list_genes){
# This to draw both plots
par(mfrow=c(2,1))
plot(x,y, main=paste0("Plot of ", gene))
hist(x, main=paste0("Plot of ", gene))
}
}
myfunction(x=c(1,5,6,2,4),y=c(6,10,53,1,5))
Since the list has 3 elements, we get 3 plots.
However, as I need to create a presentation with all the plots that I generate, I found this post with a solution to create slides for several plots inside a for loop. It is what I want, but for that, I need to save my plots into a list/variable.
object <- myfunction(x=c(1,5,6,2,4),y=c(6,10,53,1,5))
> object
NULL
I found this post (which gives you an interesting solution) but, the plots still cannot be saved into an object.
calling_myfunc <- function(){
myfunction(x=c(1,5,6,2,4),y=c(6,10,53,1,5))
}
calling_myfunc()
object <- calling_myfunc()
> object
NULL
My final objective is to create a presentation (automatically) with all of the plots that I generate from my function. As I saw in this post. But I need to save the plots into a variable.
Could anyone help me with this?
Thanks very much in advance
Although I couldn't find the way to save the plots into an object, I found a way to create a presentation with those images thanks to this post and the export package.
library(export)
list_genes <- c("GEN1", "GEN2", "GEN3")
myfunction <- function(x,y){
for(gene in list_genes){
# This to draw both plots
par(mfrow=c(2,1))
plot(x,y, main=paste0("Plot of ", gene))
hist(x, main=paste0("Plot of ", gene))
graph2ppt(file="plots.pptx", width=6, height=5,append=TRUE) } }
myfunction(x=c(1,5,6,2,4),y=c(6,10,53,1,5))
Of course, the width and height of the plots can be changed or put them as a parameter in the function.
Since the package is not available in CRAN for my current R version (4.1.2), I downloaded it from GitHub:
devtools::install_github("tomwenseleers/export")
In addition, I have found another package that I can use for the same purpose (although it adds one extra slide at the beginning, I don't know why)
library(eoffice)
list_genes <- c("GEN1", "GEN2", "GEN3")
myfunction <- function(x,y){
for(gene in list_genes){
# This to draw both plots
par(mfrow=c(2,1))
plot(x,y, main=paste0("Plot of ", gene))
hist(x, main=paste0("Plot of ", gene))
topptx(file="plots.pptx", width=6, height=5,append=TRUE)
}
}
myfunction(x=c(1,5,6,2,4),y=c(6,10,53,1,5))
PS: I found the solution to create a presentation --> How to create a presentation in R with several plots obtained by a function?
I'd like to make an object that has a QQ chart
This is my code
qqnorm(titanic$age)
qqline(titanic$age)
In ggplot, I can layer geoms on top of each other, so they can be in one object
What's the equivalent for this case?
Here's some code as an example. I had to use a different dataset, as the "Titanic" dataset's age column is non-numeric:
data("AirPassengers")
qqnorm(AirPassengers)
qqline(AirPassengers)
lines(x = 1:length(AirPassengers), rep(300, 144))
p <- recordPlot()
p
edit: to disable the plot:
dev.control('inhibit')
plot(rnorm(10))
p <- recordPlot()
dev.off()
in a loop:
for(i in 1:10){
# dev.control('inhibit')
plot(rnorm(10))
p <- recordPlot()
# dev.off()
l_plots[[i]] <- p
}
Somehow it seems difficult to combine the approaches. How about you just delete the plots in the plotting window after creating them?
There is very convenient way of plotting multiple graphs and that's with gridExtra - grid.arrange:
grid.arrange(plot1,plot2,plot3,plot4,plot5,plot6,plot7,plot8,plot9, ncol=3)
The above command draws 3x3 graphs in one window.
Now, I'm using my own lattice setup to draw unique lines etc. via
trellis.par.set(my.setup)
However using the grid.arrange command for plotting multiple plots won't pass on the setup as the output plots are in default colours.
So the question is how to pass on the my.setup onto grid.arrange or alternatively how to plot easily multiple graphs in one go for lattice.
EDIT: Reproducible example:
Data <- data.frame(Col1=rnorm(10,0,1),Col2=rexp(10,2),Col3=rnorm(10,2,2),Col4=runif(10,0,2),
Time=seq(1,10,1))
trellis.par.set(col.whitebg())
newSet <- col.whitebg()
newSet$superpose.symbol$col <- c("blue3","orange2","gray1","tomato3")
newSet$superpose.symbol$pch <- 1
newSet$superpose.symbol$cex <- 1
newSet$superpose.line$col <- c("blue3","orange2","gray1","tomato3")
trellis.par.set(newSet)
Plot1 <- xyplot(Col1+Col2~Time, Data, type="spline")
Plot2 <- xyplot(Col2+Col3~Time, Data, type="spline")
Plot3 <- xyplot(Col1+Col3~Time, Data, type="spline")
Plot4 <- xyplot(Col3+Col4~Time, Data, type="spline")
grid.arrange(Plot1,Plot2,Plot3,Plot4, ncol=2)
I guess it's got something to do with the plot.trellis method not finding the global theme settings when it's wrapped in gridExtra::drawDetails.lattice. I don't understand these lattice options, but as far as I recall you can specify them explicitly at the plot level too,
pl = list(Plot1, Plot2, Plot3, Plot4)
# do.call(grid.arrange, c(pl, nrow=1))
do.call(grid.arrange, c(lapply(pl, update, par.settings=newSet), list(nrow=1)))
I'd like to combine multiple effect plots in one window with the effects package, but don't know if there is an easy way to do so.
Here's an example that doesn't work:
d1 <-data.frame(x1=rnorm(100,0:10),y1=rnorm(100,0:10),x2=rnorm(100,0:10),y2=rnorm(100,0:10))
require(effects)
require(gridExtra)
plot1 <- plot(allEffects(mod=lm(y1~x1,d1)))
plot2 <- plot(allEffects(mod=lm(y2~x2,d1)))
grid.arrange(plot1,plot2,ncol=2)
I think you need to collect the values of allEffects components and then plot them as an 'efflist'. It looked to me that the plotting was base-graphics, but it is in fact 'lattice' if you follow the class-function trail (or if you read: ?plot.efflist )
Try this:
ef1 <-allEffects(mod=lm(y1~x1,d1))[[1]]
ef2 <- allEffects(mod=lm(y2~x2,d1))[[1]]
elist <- list( ef1, ef2 )
class(elist) <- "efflist"
plot(elist, col=2)
Interestingly, the result from plotting an efflist (which is the result from allEffects) is not a lattice graphic; it instead builds up a multipanel graphic of lattice graphics using the print.lattice methods. However, if you plot the individual effects, either by taking the elements from allEffects or by using effect, then you do get lattice graphics.
Either like this
p1 <- plot(allEffects(m1)[[1]])
p2 <- plot(allEffects(m2)[[1]])
or like this.
p1 <- plot(effect("x1", m1))
p2 <- plot(effect("x2", m2))
These can be combined with grid.arrange; the catch is that their class is c("plot.eff", "trellis") which grid.arrange doesn't recognize, so they have to be made into simple trellis objects first.
class(p1) <- class(p2) <- "trellis"
grid.arrange(p1, p2, ncol=2)
Using ggplot, is there a way of graphing several functions on the same plot? I want to use parameters from a text file as arguments for my functions and overlay these on the same plot.
I understand this but I do not know how to add the visualized function together if I loop through.
Here is an implementation of Hadley's idea.
library(ggplot2)
funcs <- list(log,function(x) x,function(x) x*log(x),function(x) x^2, exp)
cols <-heat.colors(5,1)
p <-ggplot()+xlim(c(1,10))+ylim(c(1,10))
for(i in 1:length(funcs))
p <- p + stat_function(aes(y=0),fun = funcs[[i]], colour=cols[i])
print(p)