Here is my data and plot
nmar <- seq (1, 100, 5)
position= rep(nmar, 5)
n = length (nmar )
chr = rep(1:5, each = n )
mapdata <- data.frame (chr, position,
snpname = paste("SNP-", 1:length (position), sep = ""))
mapdata
chr.lab = 1 ; mbar.col = "blue"
layout(matrix(c(1,1,2),nc=1)) # works for two but I need to extend it to
n (which is level of chr = 5)
# plot level 1
mapdata1 <- mapdata[mapdata$chr == 1,]
m <- par()$mar
m[1] <- m[3] <- 0
par(mar=m)
# Set the limits of the plot
plot(mapdata1$position,mapdata1$position-mapdata1$position, type="n",
axes=FALSE,
xlab="", ylab="Chromsome", yaxt="n" )
polygon(
c(0,max(mapdata1$position + 0.08 * max(mapdata1$position)),max(mapdata1$position)+
0.08 * max(mapdata1$position),0),
.2*c(-0.3,-0.3,0.3,0.3),
col= mbar.col
)
segments(mapdata1$position, -.3, mapdata1$position, .3 )
text(mapdata1$position, -.7, mapdata1$snpname, srt = 90, cex.lab = chr.lab)
text(mapdata1$position, .7, mapdata1$position,cex.lab = chr.lab )
text(0, labels = c("Chr 2"))
Second level
# plot level 2
mapdata2 <- mapdata[mapdata$chr == 2,]
m <- par()$mar
m[1] <- m[3] <- 0
par(mar=m)
# Set the limits of the plot
plot(mapdata2$position,mapdata2$position-mapdata1$position, type="n", axes=FALSE,
xlab="", ylab="Chromsome", yaxt="n" )
polygon(
c(0,max(mapdata2$position + 0.08 * max(mapdata2$position)),max(mapdata2$position)+
0.08 * max(mapdata2$position),0),
.2*c(-0.3,-0.3,0.3,0.3),
col= mbar.col
)
segments(mapdata2$position, -.3, mapdata2$position, .3 )
text(mapdata2$position, -.7, mapdata2$snpname, srt = 90, cex.lab = chr.lab)
text(mapdata2$position, .7, mapdata2$position,cex.lab = chr.lab )
text(0, labels = c("Chr 2"))
Output
(1) How can I automate the process for n levels - extending similar plot to n levels of chr (2) If you see the barsize with same specification has changed, may be due to different plot area. How can I adjust it so make all plots identical?
ggplot
is definitely the way to go here. But if you really want to stick with base plot
, then this function would work:
plot.as.stack= function(mapdata1, mbar.col = "blue"){
# mapdata1 <- mapdata[mapdata$chr == chr,]
m <- par()$mar
m[1] <- m[3] <- 0
par(mar=m)
# Set the limits of the plot
plot(mapdata1$position,mapdata1$position-mapdata1$position, type="n",
axes=FALSE,
xlab="", ylab="Chromsome", yaxt="n" )
polygon(
c(0,max(mapdata1$position + 0.08 * max(mapdata1$position)),max(mapdata1$position)+
0.08 * max(mapdata1$position),0),
.2*c(-0.3,-0.3,0.3,0.3),
col= mbar.col
)
segments(mapdata1$position, -.3, mapdata1$position, .3 )
text(mapdata1$position, -.7, mapdata1$snpname, srt = 90, cex.lab = chr.lab)
text(mapdata1$position, .7, mapdata1$position,cex.lab = chr.lab )
text(0, labels = paste("Chr",unique(mapdata1$chr)))
}
# Example Run.
par(mfrow=c(length(unique(mapdata$chr)),1))
x=by(mapdata,factor(mapdata$chr),plot.as.stack) # Assigned to x to prevent output
par(mfrow=c(1,1))
As you can see, I just took your code, put it into a function, and then ran by
on it. Note that this would run the function on all of the levels of chr
. You could modify it so that the function takes the value of chr instead:
plot.as.stack = function(chr){
mapdata1 <- mapdata[mapdata$chr == chr,]
...
}
And then run the function with values of chr:
par(mfrow=c(5,1))
sapply(1:5,plot.as.stack)
par(mfrow=c(1,1))