#' plot ideogram with data for one chromosome
#' @description plot ideogram with data for one chromosome
#' @param ideo output of \link{loadIdeogram}.
#' @param dataList a \link[GenomicRanges:GRangesList-class]{GRangesList} of data to plot.
#' @param parameterList a list of parameters for each dataset in the dataList.
#' The elements of the parameters could be xlabs, ylabs, etc. type could be
#' barplot, line, point, heatmap.
#' @param chrom A length 1 character vector of chromosome name.
#' @param colorSheme A character vector of giemsa stain colors.
#' @param gp parameters used for \link[grid]{grid.roundrect}.
#' @param ... parameters not used.
#' @import grid
#' @examples
#' \dontrun{
#' ideo <- loadIdeogram("hg38")
#' library(rtracklayer)
#' library(grid)
#' dataList <- ideo[seqnames(ideo) %in% "chr1"]
#' dataList$score <- as.numeric(dataList$gieStain)
#' dataList <- dataList[dataList$gieStain!="gneg"]
#' dataList <- GRangesList(dataList, dataList)
#' grid.newpage()
#' plotOneIdeo(ideo, dataList, chrom="chr1")
#' }
#'
#'
plotOneIdeo <-
function(ideo, dataList,
parameterList=list(vp=plotViewport(margins=c(.1, 4.1, 1.1, .1)),
ideoHeight=unit(1/(1+length(dataList)), "npc"),
vgap=unit(1, "lines"),
ylabs=seqlevels(ideo)[1], ylabsRot=90,
ylabsPos=unit(2.5, "lines"),
xaxis=FALSE, yaxis=FALSE,
xlab="",
types="barplot", heights=NULL,
dataColumn="score",
gps=gpar(col="black", fill="gray")),
chrom=seqlevels(ideo)[1], colorSheme=gieStain(),
gp=gpar(fill=NA, lwd=2), ...){
stopifnot(is(dataList, "GRangesList"))
stopifnot(is(parameterList, "list"))
dataList <- lapply(dataList, function(.ele){
.ele[seqnames(.ele) %in% chrom]
})
if(is(parameterList$xlab, "list")){
do.call(grid.text, args = parameterList$xlab)
}else{
if(parameterList$xlab[1]!=""){
grid.text(label=parameterList$xlab, y=unit(1.5, "lines"))
}
}
ideo <- ideo[seqnames(ideo) %in% chrom]
if(is(parameterList$vp, "viewport")){
if(identical(parameterList$vp$xscale, c(0, 1))){
parameterList$vp$xscale <- c(1, max(end(ideo)))
}
pushViewport(parameterList$vp)
if(length(parameterList$xaxis)){
if(is.logical(parameterList$xaxis)){
if(parameterList$xaxis[1]) grid.xaxis()
}else{
do.call(grid.xaxis, args = parameterList$xaxis)
}
}
}
## split the plot region into ideo layer and data layer
ideoHeight <- convertY(parameterList$ideoHeight, "npc", valueOnly = TRUE)
ideoVP <- viewport(y=ideoHeight/2,
height=ideoHeight,
name=paste0("ideoLayer", chrom))
pushViewport(ideoVP)
plotIdeo(ideo, chrom, colorSheme=colorSheme, gp=gp)
upViewport()
dataVP <- viewport(y=.5 + ideoHeight/2, height=1-ideoHeight,
name=paste0("dataLayer", chrom))
pushViewport(dataVP)
if(length(parameterList$heights)){
if(length(parameterList$heights)!=length(dataList)){
vpH <- rep(parameterList$heights, length(dataList))[1:length(dataList)]
}else{
vpH <- parameterList$heights
}
}else{
vpH <- rep(1/length(dataList), length(dataList))
}
if(length(parameterList$types)){
if(length(parameterList$types)!=length(dataList)){
types <- rep(parameterList$types, length(dataList))[1:length(dataList)]
}else{
types <- parameterList$types
}
}else{
types <- rep("barplot", length(dataList))
}
if(length(parameterList$dataColumn)){
if(length(parameterList$dataColumn)!=length(dataList)){
dataColumn <- rep(parameterList$dataColumn,
length(dataList))
if(!is.list(parameterList$dataColumn)){
dataColumn <- as.list(dataColumn)
}
dataColumn <- dataColumn[1:length(dataList)]
}else{
if(!is.list(parameterList$dataColumn)){
dataColumn <- as.list(parameterList$dataColumn)
}else{
dataColumn <- parameterList$dataColumn
}
}
}else{
dataColumn <- as.list(rep("score", length(dataList)))
}
if(length(parameterList$gps)){
if(length(parameterList$gps)!=length(dataList)){
gps <- rep(list(parameterList$gps), length(dataList))[1:length(dataList)]
}else{
if(is(parameterList$gps, "gpar")){
gps <- rep(list(parameterList$gps), length(dataList))
}else{
gps <- parameterList$gps
}
}
}else{
gps <- rep(list(gpar()), length(dataList))
}
vgap <- convertY(parameterList$vgap, "npc", valueOnly = TRUE)
for(i in seq_along(dataList)){
data.gr <- dataList[[i]]
mcols(data.gr) <- mcols(data.gr)[, dataColumn[[i]]]
if(length(mcols(data.gr))>0){
yrg <- range(as.numeric(as.matrix(mcols(data.gr))))
if(!any(is.infinite(yrg))){
this.vgap <- vgap
if(vpH[i]-vgap<=0) this.vgap <- 0
dataVPi <- viewport(y=sum(vpH[-(i:length(vpH))])+vpH[i]*.5+this.vgap,
height = vpH[i]-this.vgap,
xscale=parameterList$vp$xscale,
yscale=c(min(0, yrg[1]), max(yrg[2], 0)),
name=paste0("dataLayer", chrom, "sub", i))
pushViewport(dataVPi)
gridPlot(data.gr, gp=gps[[i]], types[i], parameterList$vp$xscale)
upViewport()
}
}
}
upViewport()
if(is(parameterList$vp, "viewport")){
upViewport()
}
if(length(parameterList$ylabs)){
ylabs <- parameterList$ylabs
if(ylabs[1]!=""){
autofitFontSize <- 0.3 *
convertY(unit(vpH[1], "npc"), "inch", valueOnly=TRUE)/
convertY(unit(1, "lines"), "inch", valueOnly = TRUE)
grid.text(label=ylabs[1], x=convertWidth(parameterList$ylabsPos, unitTo = "npc"),
rot = parameterList$ylabsRot,
gp = gpar(cex=autofitFontSize),
vp=viewport(y=ideoHeight/2,
height=ideoHeight))
if(length(ylabs)>1){
pushViewport(viewport(y=.5 + ideoHeight/2, height=1-ideoHeight))
for(i in 2:length(ylabs)){
this.vgap <- vgap
if(vpH[i-1]-vgap<=0) this.vgap <- 0
grid.text(label=ylabs[i], x=convertWidth(parameterList$ylabsPos, unitTo = "npc"),
y=unit(.5, "npc"), rot = parameterList$ylabsRot,
gp=gpar(cex=autofitFontSize),
vp=viewport(y=sum(vpH[-((i-1):length(vpH))])+vpH[i-1]*.5,
height = vpH[i-1]-this.vgap))
}
popViewport()
}
}
}
}
#' plot GRanges metadata
#' @description plot GRanges metadata for different types
#' @param gr an object of \link[GenomicRanges:GRanges-class]{GRanges} with metadata. All
#' metadata must be numeric.
#' @param gp an object of \link[grid]{gpar}
#' @param type type of the figure, could be barplot, line, point and heatmap
#' @param xscale x scale of the viewport
#' @import grid
#'
gridPlot <- function(gr, gp, type, xscale){
if(length(gr)==0) return()
x0 <- start(gr)
x1 <- end(gr)
x <- as.numeric(rbind(x0, x1))
xc <- (x0+x1)/2
y0 <- mcols(gr)
if(ncol(y0)<1){
return()
}
y <- as.matrix(y0[rep(1:nrow(y0), each=2),])
yc <- as.numeric(y0[, 1])
w <- width(gr)
switch(type,
barplot=grid.rect(x=xc, y=yc/2,
width=w, height=yc,
gp=gp, default.units = "native"),
line=grid.polyline(x=x, y=y, gp=gp,
default.units = "native"),
point=grid.points(x=xc, y=yc, gp=gp,
default.units = "native"),
heatmap={
div <- 10000
if(diff(xscale)<div) div <- diff(xscale)
ww <- ceiling(diff(xscale)/div)
img <- matrix(NA, nrow=ncol(y0), ncol=div)
wt <- tile(GRanges(as.character(seqnames(gr)[1]),
IRanges(xscale[1], xscale[2])),
n=div)[[1]]
ol <- findOverlaps(wt, gr, ignore.strand=TRUE)
qol <- unique(queryHits(ol))
if(length(gp$breaks)){
cols <- gp$col
v <- gp$breaks
}else{
rg <- range(as.numeric(as.matrix(y0)))
cols <- gp$col
if(length(cols)==0){
cols <- colorRampPalette(c("green", "black", "red"))(100)
}else{
if(length(cols)==1){
cols <- if(cols=="white")
colorRampPalette(c("black", cols))(100) else
colorRampPalette(c("white", cols))(100)
}else{
cols <- colorRampPalette(cols)(100)
}
}
v <- seq(rg[1]-1, rg[2]+1, length.out = 101)
}
group <- merge(as.data.frame(ol), data.frame(queryHits=1:div),
all=TRUE)
y00 <- as.data.frame(y0)
y01 <- matrix(nrow=nrow(group), ncol=ncol(y00))
y01[!is.na(group$subjectHits), ] <-
y00[group$subjectHits[!is.na(group$subjectHits)], ]
y01.rowsum <- rowsum(y01, group = group$queryHits)
y01.groupcnt <- table(group$queryHits)
stopifnot(identical(names(y01.groupcnt), rownames(y01.rowsum)))
y01.rowsum <- y01.rowsum/as.numeric(y01.groupcnt)
y00 <- apply(y01.rowsum, 2, function(.ele)
cols[findInterval(.ele, v)])
stopifnot(all(dim(y00)==rev(dim(img))))
img[, qol] <- y00[qol, ]
grid.raster(img, width=1, height=1)
})
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.