Skip to content

Commit

Permalink
[FEAT] - quick fix for ggridges
Browse files Browse the repository at this point in the history
  • Loading branch information
leopoldguyot committed Jul 18, 2024
1 parent 36414b0 commit cc5e0f9
Showing 1 changed file with 145 additions and 9 deletions.
154 changes: 145 additions & 9 deletions R/utils_global.R
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,7 @@ normalisation_qfeatures <- function(qfeatures, method) {
#'
#' @rdname INTERNAL_density_by_sample_plotly
#' @keywords internal
#' @importFrom plotly ggplotly
#' @importFrom ggplot2 ggplot aes
#' @importFrom ggridges geom_density_ridges
#' @importFrom SummarizedExperiment assay colData

density_by_sample_plotly <- function(qfeatures, color) {

Expand All @@ -407,11 +405,149 @@ density_by_sample_plotly <- function(qfeatures, color) {

combined_df <- rbind(combined_df, assay_df)
}
print(colData(qfeatures)[combined_df$sample, color])

combined_df$color <- colData(qfeatures)[combined_df$sample, color]

plot <- ggplot(combined_df, aes(x = intensity, y = sample, fill = color)) +
geom_density_ridges()

ggplotly(plot)
}
plotlyridges(
data = combined_df,
vardens = "intensity",
varcat = "sample")
}

# This function comes from the github repo rushkin/bitsandends
# Thanks to iliarushkin for this function

#' Mimicks \code{ggridges} but using \code{plotly} so that the output is interactive
#'
#' @param data data-frame of data to plot
#' @param vardens name of the column in \code{data} to use on the x-axis ('density variable')
#' @param varcat name of the column in \code{data} to use for splitting plots ('category variable')
#' @param linecolor line color
#' @param fillcolor fill color
#' @param fillopacity fill opacity
#' @param linewidth line width
#' @param scale vertical scale of plots, compared to the spacing between plots.
#' @param logspaced boolean, whether to use log-spaced points in calculating density
#' @param cut.from how much to cut into the region to the left of the smallest data values, in units of the bandwidth.
#' @param cut.to how much to cut into the region to the right of the greatest data values, in units of the bandwidth.
#' @param n number of points used in calculation of density
#' @param bw bandwidth to use in density calculation. if NULL, uses the default of \code{density}.
#' @param bw.separate if TRUE, will use separately estimated bandwidth in each plot, overriding \code{bw}
#' @param height.norm vertical normalization of plots. If 'integral', will normalize to unit area under the curve. If '1' will normalize to unit maximum height
#' @param round.digits number of rounding digits used in hover labels
#' @param x.min lower end of the x-axis range
#' @param height passed as \code{height} to the plotly object
#' @param width passed as \code{width} to the plotly object
#' @return a plotly object
#'
#' @rdname INTERNAL_plotlyridges
#' @keywords internal
#' @importFrom plotly plot_ly add_trace layout
#'
plotlyridges=function(data,vardens,varcat,linecolor='darkblue',fillcolor='steelblue',fillopacity=0.6,linewidth=0.5,scale=0.9,logspaced=FALSE,cut.from=0, cut.to=3,n=512,bw=NULL,bw.separate=FALSE,height.norm='integral',round.digits=2,x.min=0
,height=NULL
,width=NULL
){

data=subset(data,!is.na(data[,vardens]))

r=range(data[,vardens])

if(is.null(bw)){
if(!bw.separate){
if(logspaced){
x=log(data[,vardens])
}else{
x=data[,vardens]
}
if(length(x)>1){
bw=density(x)$bw
}else{
bw=1
}
}
}

df=aggregate(data[,vardens],by=list(varcat=data[,varcat]),FUN=function(x){

if(length(x)==0) return(NULL)
if(bw.separate){
if(length(x)==1){
bw=1
}else{
bw='nrd0'
}
}
if(logspaced){
x=log(x)
}
from=min(x,na.rm=TRUE)-cut.from*bw
to=max(x,na.rm=TRUE)+cut.to*bw
d=density(x,bw=bw,n=n,from=from,to=to)[1:2]
#Normalize height
if(height.norm=='1'){
d$y=d$y/max(d$y)
}
if(height.norm=='integral'){
d$y=d$y/(sum(d$y)*(d$x[2]-d$x[1]))
}

if(logspaced){
d$x=exp(d$x)
d$y=d$y/d$x
}


return(d)
})

text=aggregate(data[,vardens],by=list(varcat=data[,varcat]),FUN=function(x){

x=x[!is.na(x)]
q=quantile(x)
text=paste0('Observations: ',prettyNum(length(x),big.mark=','),'<br>Median: ',round(q[3],round.digits),'<br>Range: [',round(q[1],round.digits),', ',round(q[5],round.digits),']','<br>Interquartile Range: [',round(q[2],round.digits),', ',round(q[4],round.digits),']')
return(text)
})$x




catnames=df[[1]]
x=df[[2]][1:(length(df[[1]]))]
y=df[[2]][-(1:(length(df[[1]])))]



ymax=max(unlist(y),na.rm=TRUE)
y=lapply(y,function(yy){
yy=scale*yy/ymax
return(yy)
})
p=plotly::plot_ly(type='scatter',mode='lines',height=height,width=width)

fillcolor=as.vector(col2rgb(fillcolor))/255
fillcolor=rgb(fillcolor[1],fillcolor[2],fillcolor[3],alpha=fillopacity)


if(is.null(x.min)){
xaxis=list(range=r)
}else{
xaxis=list(range=c(x.min,r[2]))
}

for(i in rev(1:length(catnames))){

p=plotly::add_trace(p,x=x[[i]],y=i, line=list(color=linecolor,width=linewidth),showlegend=FALSE,hoverinfo='none')
p=plotly::add_trace(p,
x=x[[i]],y=y[[i]]+i,fill='tonexty', fillcolor=fillcolor, line=list(color=linecolor,width=linewidth),showlegend=FALSE, name=catnames[i],hoverinfo='text',text=text[i]
)

p=plotly::layout(p,
yaxis=list(tickmode='array',tickvals=(1:length(catnames)),ticktext=catnames,showline=TRUE)
,xaxis=xaxis
)

}
p
return(p)
}

0 comments on commit cc5e0f9

Please sign in to comment.