```#' Basic plot of binned vectors.
#'
#' This function plots takes two vectors, calculates the contingency table and
#' plots circles sized by the contingency table value. Optional significance vectors
#' of the values significant will shade the circles by proportion of significance.
#'
#'
#' @param yvector A vector of values represented along y-axis.
#' @param xvector A vector of values represented along x-axis.
#' @param sigvector A vector of the names of significant features (names should match x/yvector).
#' @param nbreaks Number of bins to break yvector and xvector into.
#' @param ybreak The values to break the yvector at.
#' @param xbreak The values to break the xvector at.
#' @param scale Scaling of circle bin sizes.
#' @param local Boolean to shade by signficant bin numbers (TRUE) or overall proportion (FALSE).
#' @param ... Additional plot arguments.
#' @return A matrix of features along rows, and the group membership along columns.
#' @examples
#'
#' data(mouseData)
#' mouseData = mouseData[which(rowSums(mouseData)>139),]
#' sparsity = rowMeans(MRcounts(mouseData)==0)
#' lor = log(fitPA(mouseData,cl=pData(mouseData)[,3])\$oddsRatio)
#' plotBubble(lor,sparsity,main="lor ~ sparsity")
#' # Example 2
#' x = runif(100000)
#' y = runif(100000)
#' plotBubble(y,x)
#'
plotBubble<-function(yvector,xvector,sigvector=NULL,nbreaks=10, ybreak=quantile(yvector,p=seq(0,1,length.out=nbreaks)),
xbreak=quantile(xvector,p=seq(0,1,length.out=nbreaks)),scale=1,local=FALSE,...){

ybreaks = cut(yvector,breaks=ybreak,include.lowest=TRUE)
xbreaks = cut(xvector,breaks=xbreak,include.lowest=TRUE)
contTable = lapply(levels(xbreaks),function(i){
k = which(xbreaks==i)
sapply(levels(ybreaks),function(j){
length(which(ybreaks[k]==j))
})
})
names(contTable) = levels(xbreaks)
yvec = 1:length(levels(ybreaks))
nc = length(yvec)

if(!is.null(sigvector)){
# I am calculating contTable twice if sigvector==TRUE
# This can be changed to if else statement to return two rows
contSig = lapply(levels(xbreaks),function(i){
k = which(xbreaks==i)
sapply(levels(ybreaks),function(j){
x = sum(names(yvector[k])[which(ybreaks[k]==j)]%in%sigvector)/length(which(ybreaks[k]==j))
if(is.na(x)) x = 0
x
})
})
if(local==TRUE){
contSigTable = sapply(contSig,function(i){i})
linMap <- function(x, a, b) approxfun(range(x), c(a, b))(x)
if(length(levels(ybreak))!=length(levels(xbreak))) {
warning("Not square matrix - this is not implemented currently")
}
contSigTable = matrix(linMap(contSigTable,a=0,b=1),nrow=length(levels(ybreaks)))
for(i in 1:length(levels(ybreaks))){
contSig[[i]] = contSigTable[,i]
}
}
} else {
contSig = lapply(levels(xbreaks),function(i){
k = which(xbreaks==i)
sapply(levels(ybreaks),function(j){
1
})
})
}

medianSizes = median(unlist(contTable))
plot(y=yvec,x=rep(1,nc),cex=scale*contTable[[1]]/medianSizes,
xlim=c(-0.25,nc+.25),ylim=c(-0.25,nc+.25),bty="n",xaxt="n",yaxt="n",
xlab="",ylab="",pch=21,...,bg=rgb(blue=1,red=0,green=0,alpha=contSig[[1]]))
for(i in 2:length(contTable)){
points(y=yvec,x=rep(i,nc),cex =scale*contTable[[i]]/medianSizes,pch=21,bg=rgb(blue=1,red=0,green=0,alpha=contSig[[i]]))
}
axis(1,at = 1:nc,labels=levels(xbreaks),las=2,cex.axis=.5)
axis(2,at = 1:nc,labels=levels(ybreaks),las=2,cex.axis=.5)

res = cbind(as.character(ybreaks),as.character(xbreaks))
colnames(res) = c("yvector","xvector")
rownames(res) = names(yvector)
if(is.null(sigvector)){
sig = rep(0,nrow(res))
sig[which(rownames(res)%in%sigvector)] = 1
res = cbind(res,sig)
}
invisible(res)
}
```