#' Plot time-series switches of a pair of isoforms
#'
#' @param data2plot the transcript isoform expression data for switch plots with rows of isoforms and columns of samples. See \code{TSIS.data$data.exp} for details.
#' @param scores the output scores of functions \code{\link{iso.switch}} and \code{\link{score.filter}}. Default is NULL. To show score labels on the plot,
#' the scores must be provided.
#' @param iso1,iso2 character string names of isoforms to plot.
#' the input \code{data2plot} must be a data frame of two rows and the row names are used as isoforms to plot.
#' @param gene.name a character string of gene name to show as the title of the plot. If \code{gene.name=NULL}, the plot title will be "iso1_vs_iso2".
#' @param y.lab the y axis label of the plot, default is "Expression".
#' @param make.plotly logical, to plot \code{\link{plotly}} format figures (TRUE) or ggplot2 format figures(FALSE)?. See details in \code{\link{ggplotly}} in \code{\link{plotly}} R pacakge.
#' @param times a numeric vector of time labellings of all the relicated samples, e.g. 1,1,1,2,2,2,3,3,3,...
#' @param prob.cutoff the cut-off of switch frequencies/probabilities to label the switch points.
#' @param x.lower.boundary,x.upper.boundary Specifies the time frame of interest to investigate the isoform switches.
#' @param show.region logical, to highlight the time frame under investigation (TRUE) or not (FALSE)?
#' @param show.scores logical, to show score labels on the plot (TRUE) or not (FALSE)? The \code{scores} object must be provided.
#' @param error.type the error type used to show the error bar in the plots. Options are "stderr" for standard error and "sd" for standard deviation. See details in \code{\link{data.error}}.
#' @param show.errorbar logical, to show error bar (TRUE) or not (FALSE) in the error bar plot.
#' @param errorbar.width,errorbar.size the width and size of error bars. See detials in \code{\link{geom_errorbar}} in \code{\link{ggplot2}} R pacakge.
#' @param line.width,point.size line width and point marker size of the plots.
#' @param spline logical, to plot the spline smoothed lines (TRUE) or the lines of mean expression (FALSE).
#' @param spline.df the degree of freedom used for spline. The value must be the same as in the function \code{\link{iso.switch}}. See spline details in \code{\link{geom_smooth}} in \code{\link{ggplot2}}
#' and \code{\link{ns}} in \code{\link{splines}}.
#' @param ribbon.plot logcial, to make ribbon plot (TRUE) or error bar plot (FALSE). See ribbon plot details in \code{\link{geom_smooth}} in \code{\link{ggplot2}} R pacakge.
#'
#'
#'
#' @examples
#'
#' #generate random datasets
#' set.seed(100)
#' data2plot<-data.frame(matrix(abs(rnorm(60)),nrow=2),row.names = c('iso1','iso2'))
#' #error bar plot
#' plotTSIS(data2plot=data2plot,scores=NULL,iso1=NULL,iso2=NULL,gene.name=NULL,
#' y.lab='Expression',make.plotly=F,times=rep(1:10,each=3),prob.cutoff=0.5,x.lower.boundary=3,
#' x.upper.boundary=8,show.region=T,error.type='stderr',ribbon.plot = F)
#'
#' #ribbon plot
#' plotTSIS(data2plot=data2plot,scores=NULL,iso1=NULL,iso2=NULL,gene.name=NULL,
#' y.lab='Expression',make.plotly=F,times=rep(1:10,each=3),prob.cutoff=0.5,x.lower.boundary=3,
#' x.upper.boundary=8,show.region=T,error.type='stderr',ribbon.plot = T)
#'
#' @return a ggplot2 or \code{\link{ggplotly}} (if \code{plotly=TRUE}) plot.
#' @export
#'
#' @seealso \code{\link{ggplotly}}, \code{\link{iso.switch}}, \code{\link{score.filter}}, \code{\link{data.error}}, \code{\link{geom_smooth}}, \code{\link{ns}}
#'
plotTSIS<-function(data2plot,scores=NULL,iso1=NULL,iso2=NULL,gene.name=NULL,y.lab='Expression',make.plotly=F,
times,prob.cutoff=0.5,x.lower.boundary=9,x.upper.boundary=17,show.region=T,show.scores=T,
error.type='stderr',show.errorbar=T,errorbar.width=0.1,errorbar.size=0.5,line.width=1,
point.size=3,marker.size=1,
spline=F,spline.df=NULL,ribbon.plot=F){
require(ggplot2)
if(is.null(spline.df))
spline.df<-floor((unique(times)-2)*2/3)
gg_color_hue <- function(n) {
hues = seq(15, 375, length = n + 1)
hcl(h = hues, l = 65, c = 100)[1:n]
}
y.upper <- function(x){mean(x) + data.error(x)}
y.lower<-function(x){mean(x) - data.error(x)}
if(is.null(iso1) | is.null(iso2)){
iso1<-rownames(data2plot)[1]
iso2<-rownames(data2plot)[2]
}
data2plot<-data2plot[c(iso1,iso2),]
if(is.null(gene.name))
gene.name<-paste0(iso1,'_vs_',iso2)
data2plot<-data.frame(rbind(data.frame(isoforms=iso1,times=times,value=as.numeric(data2plot[iso1,])),
data.frame(isoforms=iso2,times=times,value=as.numeric(data2plot[iso2,]))))
##ribbon plot
if(ribbon.plot){
if(spline){
data2plot<-data.frame(data2plot[,1:2],mean=data2plot$value,error=0)
# data2plot$times<-factor(data2plot$times,levels = unique(data2plot$times))
g<-ggplot(data2plot, aes(x=times, y=mean,group=isoforms,color=isoforms,fill=isoforms,shape=isoforms)) +
geom_point(size=marker.size) +theme_bw()+
geom_smooth(method = "lm",formula = y ~ splines::ns(x, spline.df),size=line.width)
} else {
data2plot<-data.frame(data2plot[,1:2],mean=data2plot$value,error=0)
# data2plot$times<-factor(data2plot$times,levels = unique(data2plot$times))
g <- ggplot(data2plot, aes(x=times, y=mean,group=isoforms,color=isoforms,fill=isoforms,shape=isoforms)) +
geom_point(size=marker.size) +theme_bw()+
stat_summary(fun.y=mean,geom='line',size=line.width)+
stat_summary(fun.y=mean,geom = 'ribbon',fun.ymax = y.upper,fun.ymin = y.lower,alpha=0.3,colour=NA)
}
##error bar plots
} else{
if(spline){
values<-by(data2plot$value,INDICES = data2plot$isoforms,simplify = T,
FUN = function(x) ts.spline(x,times = times,df=spline.df,se.fit=T))
x1 <- data.frame(isoforms=iso1,times=unique(times),
mean=values[[iso1]]$fit,
error=values[[iso1]]$se.fit)
x2 <- data.frame(isoforms=iso2,times=unique(times),
mean=values[[iso2]]$fit,
error=values[[iso2]]$se.fit)
data2plot<-rbind(x1,x2)
} else {
data2plot <- by(data2plot,INDICES = interaction(data2plot$isoforms,data2plot$times,sep = '_at_'),function(x){
data.frame(isoforms=unique(x$isoforms),
times=unique(x$times),
mean=mean(x$value),
error=data.error(x$value,error.type = error.type))
})
data2plot <- do.call(rbind,data2plot)
}
# colnames(data2plot)<-c('isoforms','times','mean','error')
g<-ggplot(data2plot,aes(x=times,y=mean,group=isoforms,shape=isoforms,color=isoforms))+theme_bw()+
geom_line(size=line.width)+geom_point(size=point.size,aes(fill=isoforms))+
scale_x_continuous(breaks = unique(times),labels = unique(times))
if(show.errorbar)
g<-g+geom_errorbar(data=data2plot,aes(ymin=mean-error,ymax=mean+error),width=errorbar.width,color='black',
size=errorbar.size)
}
if(is.null(scores))
idx=NULL else idx<-which(scores$iso1 %in% c(iso1,iso2) & scores$iso2 %in% c(iso1,iso2) & scores$prob>=prob.cutoff)
if(length(idx)==0){
g<-g } else {
sub.scores<-scores[idx,]
data2points<-data.frame(isoforms='switch_points',times=sub.scores$x.value,mean=sub.scores$y.value,error=0)
g<-g+geom_point(data=data2points,aes(x=times,y=mean,color=isoforms,fill=isoforms,shape=isoforms),size=point.size)+
scale_color_manual(values=c(gg_color_hue(2),rep('black',length(idx))),breaks=c(iso1,iso2,rep('switch_points',length(idx))))+
scale_fill_manual(values=c(gg_color_hue(2),rep('black',length(idx))),breaks=c(iso1,iso2,rep('switch_points',length(idx))))+
scale_shape_manual(values=c(15,17,rep(16,length(idx))),breaks=c(iso1,iso2,rep('switch_points',length(idx))))
if(show.scores)
g<-g+annotate('text',x = 1.1*sub.scores$x.value, y =sub.scores$y.value+max(data2plot$mean)/20,
label = paste0('prob=',round(sub.scores$prob,2),'; diff=',round(sub.scores$diff,2),'; cor=',round(sub.scores$cor,2)))
}
if(show.region){
g<-g+annotate("rect", xmin = x.lower.boundary, xmax = x.upper.boundary, ymin = -Inf, ymax = Inf,alpha = 0.2,color='skyblue',fill='skyblue')+
annotate("text",x=mean(c(x.upper.boundary,x.lower.boundary)),
y=max(data2plot$mean+data2plot$error),label='Region for investigation',color='blue',size=5)+
geom_vline(xintercept = c(x.lower.boundary,x.upper.boundary),linetype=3,lwd=1,color='skyblue',alpha=1)
}
g<-g+labs(title=paste("Isoforms of gene:",gene.name),x='Time points',y=y.lab)
if(make.plotly)
plotly::ggplotly(g) else g
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.