R/TargetExperiment-plot.R

Defines functions plot.TargetExperiment

Documented in plot.TargetExperiment

#'Plot TargetExperiment object overview.
#'
#'\code{plot} allows a fast and simple representation of one feature panel
#'using a polar histogram plot. Histogram bar reflects the percentage of 
#'features that have shown the analyzed attribute in a user set interval.
#'The resulting graph can be busy and might be better off saved.
#'
#'@param x TargetExperiment/TargetExperimentList class object.
#'@param y not used but necessary for redefining the generic function.
#'@param attributeThres Numeric indicating the interval extreme values.
#'@param binSize Numeric indicating bin width. Should probably be left
#'as 1, as other parameters are relative to it.
#'@param spaceGene Numeric. Space between bins.
#'@param spaceChr Numeric. Space between chromosomes.
#'@param innerRadius Numeric. Radius of the inner circle.
#'@param outerRadius Numeric. Radius of the outer circle. 
#'@param guides A vector with percentages to use for the white guide lines.
#'@param alphaStart Numeric offset from 12 o'clock in radians.
#'@param circleProportion Numeric proportion of the circle to cover.
#'@param direction Character indicating if the increasing count goes from or
#'to the center.
#'@param chrLabels Logical. Chromosome names must be plotted?.
#'
#'@return a ggplot2 graph.
#'
#'@include TargetExperiment-statistics.R
#'@docType methods
#'@name plot
#'@rdname TargetExperiment-plot
#'@import ggplot2
#'@importFrom grDevices colorRampPalette
#'@importFrom grDevices hcl
#'@importFrom graphics plot
#'@importFrom Hmisc capitalize
#'@aliases plot,TargetExperiment,plot.TargetExperiment
#'@seealso \code{\link{plotFeatPerform}}
#'@note see full example in \code{\link{TargetExperiment-class}}
#'@author Gabriela A. Merino \email{gmerino@@bdmg.com.ar}, Cristobal Fresno
#'\email{cfresno@@bdmg.com.ar}, Yanina Murua \email{ymurua@leloir.org.ar},
#'Andrea S. Llera \email{allera@leloir.org.ar} and Elmer A. Fernandez 
#'\email{efernandez@bdmg.com.ar}
#'@references
#'\url{http://www.r-bloggers.com/polar-histogram-pretty-and-useful/}
#'@examples
#'## Loading the TargetExperiment object
#'data(ampliPanel, package="TarSeqQC")
#'# Definition of the interval extreme values
#'attributeThres<-c(0,1,50,200,500, Inf)
#'
#'## Plot panel overview
#'g<-plot(ampliPanel, attributeThres, chrLabels =TRUE)
#'if(interactive()){
#'g
#'}
#'@export plot.TargetExperiment
plot.TargetExperiment <- function(x, y, attributeThres=c(0, 1, 50, 200, 500, 
Inf),binSize=1, spaceGene=0.2,  spaceChr=1.2,  innerRadius=0.3,
outerRadius=1, guides=c(20,40,60,80),  alphaStart=-0.3,  
circleProportion=0.95, direction="inwards",  chrLabels=FALSE,...){
    if(attributeThres[1] !=0){
        attributeThres<-c(0,attributeThres)
    }
    if(attributeThres[length(attributeThres)] !=Inf){
        attributeThres<-c(attributeThres, Inf)
    }
    df_panel<-as.data.frame(getFeaturePanel(x))
    df_panel[,"names"]<-rownames(df_panel)
    attribute<-getAttribute(x)
    if(!(attribute %in% c("coverage", "medianCounts"))){
        stop("Attribute slot should be defined in order to call biasExploration
            function")
    }
    # creating a 'score' variable to group features according to the attribute
    #'intervals
    df_panel[,"score"]<-cut(df_panel[,attribute], breaks=attributeThres, 
        include.lowest=TRUE, right=FALSE, dig.lab = 6)
    score_levels<-levels(df_panel[,"score"])

    df_panel<-df_panel[order(df_panel[,"seqnames"],df_panel[,"start"],
        df_panel[,"gene"], df_panel[,"score"]),]
    geneFeat<-sapply(unique(df_panel[,"gene"]), function(gene){
        paste(gene, "(",length(which(df_panel[,"gene"] == gene)), ")", sep="")
    })
    gene_idx<-match(df_panel[, "gene"],unique(df_panel[,"gene"]))
    gene<-geneFeat[gene_idx]
#     df_panel<-cbind(df_panel, gene)
    df_panel[,"gene"]<-gene

    aux<-sapply(unique(df_panel[,"seqnames"]), function(chr){
        info<-t(sapply(unique(df_panel[df_panel[,"seqnames"] == chr,"gene"]), 
        function(gene){
            return(as.matrix(table(df_panel[which(df_panel[,"gene"] == gene &
            df_panel[,"seqnames"]== chr),"score"])))
        }))
        return(list(info))
    })
    aux<-do.call(rbind,aux)
    rownames(aux)<-unique(df_panel[, "gene"])

    gene_names<-as.list(unique(as.character(df_panel[, "gene"])))
    df_panel<-do.call(rbind,lapply(unique(df_panel[, "gene"]), function(gene){
        seqnames<-rep(as.character(unique(df_panel[df_panel[,"gene"] == gene, 
            "seqnames"])), times=ncol(aux))
        score<-levels(df_panel[, "score"])
        values<-aux[rownames(aux) == gene,]
        gene<-rep(gene, times=ncol(aux))
        return(data.frame(seqnames=seqnames, gene=gene, score=score, 
            values=values))
    }))
    df_panel[,"score"]<-factor(as.character(df_panel[,"score"]),score_levels)
    df_panel<-ddply(df_panel,c("seqnames","gene"),transform,values= cumsum(
        values/(sum(values))))
    if(any(is.na(df_panel[,"values"]))){
        df_panel[is.na(df_panel[, "values"]), "values"]<-0
    }

    df_panel<-ddply(df_panel, c("seqnames", "gene"), transform, previous= c(0, 
        head(values, length(values)-1)))
    df_panel<-df_panel[order(df_panel[,"seqnames"], df_panel[,"gene"]),]
    df_panel$indexGene<-factor(df_panel[, "gene"], levels= as.character(
        unique(df_panel[, "gene"])))
    levels(df_panel$indexGene)<-1:length(levels(df_panel[, "indexGene"]))

    df_panel$indexChr<-factor(df_panel[,"seqnames"], levels=as.character(
        unique(df_panel[,"seqnames"])))
    levels(df_panel$indexChr)<-1:length(levels(df_panel[,"indexChr"]))
    df_panel[,which(names(df_panel) %in% c("indexGene", "indexChr"))]<-apply(
        df_panel[,which(names(df_panel) %in% c("indexGene", "indexChr"))],
            2,as.numeric)

    affine<-switch(direction,
        'inwards'= function(y) (outerRadius-innerRadius)*y+innerRadius,
        'outwards'=function(y) (outerRadius-innerRadius)*(1-y)+innerRadius,
        stop(paste("Unknown direction value")))
    xmin<-(df_panel[,"indexGene"]-1)*binSize + 
        (df_panel[,"indexGene"]-1)*spaceGene +
        (df_panel[,"indexGene"]-1)*(spaceChr-spaceGene)
    
    xmax<-xmin+binSize
    ymin<-affine(1-df_panel[,"previous"])
    ymax<-affine(1-df_panel[,"values"])
    df_panel<-cbind(df_panel, xmin, xmax, ymin, ymax)
    guidesDF<-data.frame(
        xmin=rep(xmin, times=length(guides)), y=rep(1-guides/100, 
        times=1, each=nrow(df_panel)))
    xend<-guidesDF[,"xmin"]+binSize
    guidesDF<-cbind(guidesDF, xend)
    guidesDF$y<-affine(guidesDF[,"y"])
    # Building the ggplot object
    totalLength<-tail(df_panel[, "xmin"]+binSize+spaceChr,1)/circleProportion-0
    p<-ggplot(df_panel)+geom_rect(aes( xmin=xmin, xmax=xmax, ymin=ymin, 
        ymax=ymax,fill=score))
    colors<-colorRampPalette(c("red", "green"))(length(score_levels))
    names(colors)<-score_levels
    p<-p+scale_fill_manual(name=paste(attribute, "interval", sep=" "),
                breaks=score_levels, values=colors)
    # names labels
    readableAngle<-function(x){
        angle<-x*(-360/totalLength)-alphaStart*180/pi+90
        angle+ifelse(sign(cos(angle*pi/180))+sign(sin(angle*pi/180))==-2,180,0)
    }
    readableJustification<-function(x){
        angle<-x*(-360/totalLength)-alphaStart*180/pi+90
        ifelse(sign(cos(angle*pi/180))+sign(sin(angle*pi/180))==-2,1,0)
    }

    df_panelItemLabels<-ddply(df_panel, "gene", summarize, xmin=xmin[1])
    df_panelItemLabels$x<-df_panelItemLabels[,"xmin"]+binSize/2
    angle<-readableAngle(df_panelItemLabels[,"xmin"] + binSize/2)
    hjust<-readableJustification(df_panelItemLabels[,"xmin"] + binSize/2)
    df_panelItemLabels<-cbind(df_panelItemLabels, angle, hjust)
    p<-p+geom_text(aes(x=x, label=gene, angle=angle, hjust=hjust), y=1.02, 
        size=3, vjust=0.5, data=df_panelItemLabels)
    # guides  
    p<-p+geom_segment(aes( x=xmin, xend=xend, y=y, yend=y), colour="white",
        data=guidesDF)

    # label for guides
    label<-paste(guides, "% ", sep='')
    guideLabels<-data.frame( x=0, y=affine(1-guides/100), label=label)

    p<-p+geom_text( aes(x=x, y=y, label=label), data=guideLabels, 
        angle=-alphaStart*180/pi, hjust=1, size=4)

    # gene labels
    if(chrLabels){
        chrLabelsDF<-aggregate(formula=xmin~seqnames,data=df_panel,
            FUN=function(s){
                mean(s+binSize)
            })
#         chrLabelsDF<-within(chrLabelsDF,{
#             x<-xmin
#             angle<-xmin*(-360/totalLength)-alphaStart*180/pi
#         })
        chrLabelsDF$x<-chrLabelsDF[,"xmin"]
        chrLabelsDF$angle<-chrLabelsDF[,"xmin"]*(-360/totalLength) - 
            alphaStart*180/pi
        p<-p+geom_text( aes( x=x, label=seqnames, angle=angle), 
            data=chrLabelsDF, y=1.4)
    }  
    p<-p+theme(panel.background=element_blank(), axis.title.x=element_blank(),
        axis.title.y=element_blank(), panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(), axis.text.x=element_blank(),
        axis.text.y=element_blank(), axis.ticks=element_blank() )
    p<-p+xlim(0,tail(df_panel[,"xmin"]+binSize+spaceChr,1)/circleProportion)
    p<-p+ylim(0,outerRadius+0.2)
    p<-p+guides(fill=guide_legend(title=paste(capitalize(attribute), 
        "_intervals", sep="")))
    p<-p+coord_polar(start=alphaStart)
    p

}
#'@S3method plot TargetExperiment
## S4 method dispatches to S3
setMethod("plot", "TargetExperiment", plot.TargetExperiment)
gamerino/TarSeqQC documentation built on Feb. 3, 2020, 9:19 p.m.