library(componentSkeleton) mmclustplot<-function(data,filtered,filtered.id.col, cluster.clust.col, plotType,file.name, pch.plot, pres.type, plot.centres, caption, cf){ unique.cluster.ids <- unique(data[,cluster.clust.col]) # The number of points in each cluster cluster.numbers <- sapply(unique.cluster.ids, function(x) sum(x == data[,cluster.clust.col])) names(cluster.numbers) <- unique.cluster.ids Dat <- data[, -which(colnames(data) == cluster.clust.col)] # Calculate the centres of the clusters. centres <- matrix(nrow=length(unique.cluster.ids), ncol=ncol(Dat)) rownames(centres) <- unique.cluster.ids colnames(centres) <- colnames(Dat) for(col in 1:ncol(Dat)) { for(cluster.id in unique.cluster.ids) { centres[cluster.id, col] <- mean(Dat[data[,cluster.clust.col]==cluster.id,col],) } } #Setting appropriate colours for plotting colours=rainbow(length(unique.cluster.ids)) names(colours) <- sort(unique.cluster.ids, decreasing=F) if(!is.null(filtered)){ include.clusters=unique(data[which(rownames(data)%in%filtered[,filtered.id.col]),cluster.clust.col]) colours[setdiff(unique.cluster.ids, include.clusters)]='gray' } if(plotType=='regular2d'){ png(file.name, width=(ncol(Dat)+1)*500, height=(ncol(Dat)+1)*500) par(mfrow=rep(ncol(Dat),2)) for(x.plot.counter in 1:(ncol(Dat))){ for(y.plot.counter in 1:(ncol(Dat))){ if(x.plot.counter==y.plot.counter){ plot(1, type="n", axes=F, xlim=c(0,1), ylim=c(0,1), xlab="", ylab="") text(0.5,0.5,colnames(Dat[x.plot.counter]), cex=10) } else{ # Set margins big enough. par(mar=c(5,5,4,2)+0.1) plot(Dat[,y.plot.counter],Dat[,x.plot.counter], col=colours[data[,cluster.clust.col]], xlim=c(min(Dat[,y.plot.counter]), max(Dat[,y.plot.counter])+((max(Dat[,y.plot.counter])- min(Dat[,y.plot.counter]))/4)), ylim= c(min(Dat[,x.plot.counter]), max(Dat[,x.plot.counter])+((max(Dat[,x.plot.counter])- min(Dat[,x.plot.counter]))/4)), pch=pch.plot, type=pres.type ,xlab=colnames(Dat)[y.plot.counter], ylab=colnames(Dat)[x.plot.counter], cex.lab=2, cex.axis=2) if(plot.centres) { points(centres[,y.plot.counter], centres[,x.plot.counter], pch=21, cex=2.5, bg=colours[rownames(centres)], col='black') } legend('topright',legend=paste('Cluster', sort(unique.cluster.ids, decreasing=F),'[', cluster.numbers[sort(unique.cluster.ids, decreasing=F)],',',format(cluster.numbers[sort(unique.cluster.ids, decreasing=F)]/sum(cluster.numbers), digits=1, scientific=F),']'), fill=colours[sort(unique.cluster.ids, decreasing=F)],title="Cluster [frequency, ratio]") } } } dev.off() } else if(plotType=='regular3d'){ if(ncol(Dat)<3){ write.error(cf, 'Error in plotting! The number of channels to cluster should be at least 3, for regular 3d plotting') return(PARAMETER_ERROR) } require(scatterplot3d) require(rgl) plotting.dim=as.matrix(combn(ncol(Dat),3)) image.dim=trunc(sqrt(ncol(plotting.dim)))+ceiling(sqrt(ncol(plotting.dim))%%1) png(file.name, width=image.dim*500, height=image.dim*500) par(mfrow=rep(image.dim,2)) if (length(unique.cluster.ids)>32) { colours=rainbow(length(unique.cluster.ids)) names(colours) <- sort(unique.cluster.ids, decreasing=F) }else { library(RColorBrewer) colours=c(brewer.pal(8,"Dark2"),brewer.pal(12,"Set3"),brewer.pal(12,"Paired"))[1:length(unique.cluster.ids)] names(colours) <- sort(unique.cluster.ids, decreasing=F) } if(!is.null(filtered)){ include.clusters=data[which(rownames(data)%in%filtered[,filtered.id.col]),cluster.clust.col] colours[-unique(include.clusters)]='gray' } for(col.counter in 1:ncol(plotting.dim)){ plot_res=scatterplot3d(Dat[,plotting.dim[,col.counter]], color=colours[data[,cluster.clust.col]], pch=pch.plot, type= pres.type, main=paste(colnames(Dat)[plotting.dim[,col.counter]], sep=',')) if(plot.centres) plot_res$points3d(centres[,plotting.dim[,col.counter]], pch=21, cex=2.5,bg=colours[unique.cluster.ids], col='black') legend('topright',legend=paste('Cluster', sort(unique.cluster.ids, decreasing=F), '[',cluster.numbers[as.character(sort(unique.cluster.ids, decreasing=F))],',',format(cluster.numbers[as.character(sort(unique.cluster.ids, decreasing=F))]/sum(cluster.numbers), digits=1, scientific=F),']'), fill=colours[sort(unique.cluster.ids, decreasing=F)], title="Cluster [frequency, ratio]") } if (image.dim^2 > ncol(plotting.dim)) for(text.counter in (ncol(plotting.dim)+1):(image.dim^2)){ plot(1, type="n", axes=F, xlim=c(0,1), ylim=c(0,1), xlab="", ylab="") text(0.5,0.5,'AFACS', col='orange', cex=2) } dev.off() } else{ write.error(cf, paste('Error in Writing',file.name, ': The plotting type is not valid')) return(PARAMETER_ERROR) } tex <- latex.figure(file.name, caption= sprintf(caption, file.name), fig.label = sprintf('fig:%s', get.metadata(cf, 'instanceName')), image.width=20, image.height=20) return(tex) } ###################### ## Execute function ## ###################### execute <- function(cf){ # Read input cluster.files <- get.input(cf,'clusterFiles') if (input.defined(cf, 'clusters')) { clusters.array <- Array.read(cf, 'clusters') }else { clusters.array <- NULL } if(input.defined(cf, 'filteredFiles')) { filtered.files <- get.input(cf,'filteredFiles') }else { filtered.files <- NULL } if (input.defined(cf, 'filtered')) { filtered.array <- Array.read(cf, 'filtered') }else { filtered.array <- NULL } # Read parameters plot.type <- get.parameter(cf, 'plotType') plot.centres <- get.parameter(cf, "plotClusterCentres", "boolean") pagebreak <- get.parameter(cf, 'pagebreak', 'boolean') channels.to.plot <- unlist(strsplit(get.parameter(cf,"channelsToPlot"), split=',')) pres.type <- get.parameter(cf, "presentationType") pch.plot <- get.parameter(cf, 'pch', 'string') cluster.clust.col <- get.parameter(cf,'clusterClustIDCol') instance.name <- get.metadata(cf, 'instanceName') section.title <- get.parameter(cf, 'sectionTitle') section.type <- get.parameter(cf, 'sectionType') caption <- get.parameter(cf, 'caption') filtered.id <- get.parameter(cf,'filteredIDCol') filtered.id.col <- get.parameter(cf,'filteredIDCol') cluster.id.col=get.parameter(cf,'clusterIDCol') if (pres.type %in% c("points","lines","pointsLines", "histogram", "stairs", "otherStairs", "overplotted", "linesApart")) { pres.type <- switch(pres.type, "points"="p", "lines"="l", "pointsLines"="b", "histogram"="h", "stairs"="s", "otherStairs"="S", "overplotted"="o", "linesApart"="c") } else if (!press.type %in% c("p", "l", "b", "h", "s", "S", "o", "c")){ write.error(cf, paste('Error in plotting! The visualisation type', pres.type, 'is not supported')) return(PARAMETER_ERROR) } if(suppressWarnings(!is.na(as.numeric(pch.plot)))) { pch.plot=as.numeric(pch.plot) }else { pch.plot=as.character(pch.plot) } # Create report output output.report <- get.output(cf,'report') dir.create(output.report) # Files to plot. cluster.file.names <- as.list(dir(cluster.files, pattern=".csv", full.names=T)) names(cluster.file.names) <- sub(".csv", "", as.list(dir(cluster.files, pattern=".csv", full.names=F))) if(!is.null(clusters.array)) { for(i in 1:Array.size(clusters.array)) { cluster.file.names[[Array.getKey(clusters.array, i)]] <- Array.getFile(clusters.array,i) } } #filtered input if(!is.null(filtered.files)){ filtered.file.names <- as.list(dir(filtered.files, pattern=".csv", full.names = T)) names(filtered.file.names) <- sub(".csv", "", as.list(dir(filtered.files, pattern=".csv", full.names = F))) }else { filtered.file.names <- list() } if(!is.null(filtered.array)) { for(i in 1:Array.size(filtered.array)) { filtered.file.names[[Array.getKey(filtered.array, i)]] <- Array.getFile(filtered.array,i) } } # Collect results results <- list() for(i in 1:length(cluster.file.names)) { # Read in the data to plot data=CSV.read(cluster.file.names[[i]]) row.names(data)=data[,cluster.id.col] if(!is.null(filtered.files)) { corresponding.file <- filtered.file.names[[which(names(filtered.file.names) == names(cluster.file.names)[i])]] filtered=CSV.read(corresponding.file) }else { filtered=NULL } data.clusters=as.character(unlist(data[,cluster.clust.col])) channels.to.plot.found <- colnames(data)[which(colnames(data) %in% channels.to.plot)] data=data[,channels.to.plot.found] data[[cluster.clust.col]] <- data.clusters image.file.name <- sprintf("%s-%s.png", instance.name, names(cluster.file.names)[i]) # create the Plotting images tex <- mmclustplot(data,filtered,filtered.id.col, cluster.clust.col, plot.type, paste(output.report, image.file.name, sep='/'), pch.plot=pch.plot, pres.type=pres.type, plot.centres=plot.centres, caption, cf) results[[i]] <- tex } ## Create Latex report. tex <- character() if (pagebreak) { tex <- c(tex, '\\clearpage{}') } if(section.title != "") { tex <- c(tex, sprintf("\\%s{%s}", section.type, section.title)) } tex=c(tex, paste(gsub('/.*/','',unlist(results)), collapse='\n')) latex.write.main(cf, 'report', tex) } main(execute)