#' @title Visualize interactive protein profile
#'
#' @description
#' \code{ProfileInteract} allows you to visualize protein profile from the organelle(s) you want
#' interactively or not, and highlight specific proteins.
#' It is based on the plotDist function from pRoloc package.
#'
#' @param obj A \code{\link{MSnSet}} object
#' @param mrk The name of the column which contains the markers from the data
#' @param Organelle A character vector which contains the organelle(s) that you want to see the protein profile
#' @param Interact A logical argument to tell if you want an interactive plot
#' @param mytitle A logical argument to tell if you want to change the first part of the subtitle (name of the data)
#' @param TITLE A character which be your title (use with mytitle = TRUE)
#' @param Clust A logical argument to tell if you use clustered data.
#' (mrk should be equal to "knn" or orther clustering algorithm or any name of your data).
#' @param one_pr A logical argument to tell if you want to highlight a specific protein profile (or several);
#' also tell if you want to plot all markers when protein is null
#' @param mean_prof A logical argument to tell if you want to see the profile's mean of all proteins
#' @param protein A character vector which contains the proteins you want to highlight.
#' if NULL, show all the proteins
#' @param xLab A character which will be the name of the x-axis
#' @param yLab A character which will be the name of the y-axis
#'
#' @return A gpplot or ggplotly object : the protein profiles
#'
#' @seealso \code{\link{ggplotly}}, \code{\link{gghighlight}} and \code{\link{plotDist}} from Proloc package
#'
#' @export
#'
#' @examples
#'
#' library(pRolocExtra)
#' Profil_interact(tan2009r1)
ProfileInteract <- function(obj, mrk = "markers", Organelle = "Golgi", Interact = TRUE,
mytitle = FALSE, TITLE = "Profile", Clust = FALSE, mean_prof = FALSE,
one_pr = FALSE, protein = NULL, xLab = "Fractions", yLab = "Intensity") {
#check the fractions names (from plotDist from pRoloc package)
if (is.character(MSnbase::sampleNames(obj)) & length(MSnbase::sampleNames(obj)) == 1) {
if (sum(MSnbase::sampleNames(obj) %in% names(MSnbase::pData(obj))) != 1)
stop("'fractions' must be a single pData name.")
MSnbase::sampleNames(obj) <- as.character(MSnbase::pData(obj)[, MSnbase::sampleNames(obj)])
}
all_mrk <- as.character(unique(MSnbase::fData(obj)[[mrk]])) #get all the markers from the column selected
if (Clust){
if (!one_pr){
#get the number of proteins of which we know their localization (the training set for each organelle)
npr_kn <- length(which(MSnbase::fData(obj)$markers == Organelle))
}
else {
npr_kn <- length(which(MSnbase::fData(obj)$markers != "unknown")) #same thing but for all organelle
}
prtx <- paste("proteins", "(based on", npr_kn, "proteins)") #will be used for the graph title
}
else {
prtx <- "proteins from known location"
}
if (!mytitle){ #put your own title
subt <- deparse(substitute(obj)) #if not, take the name of the data (the obj argument)
}
else {
subt <- TITLE
}
if (!one_pr){
i <- which(!is.na(match(MSnbase::fData(obj)[[mrk]], Organelle))) #find the proteins that are in the organelle
npr <- length(i) #number of protein in this organelle
m_tit <- paste(Organelle, collapse = ", ") #will be used for the main graph title
}
else {
i <- which(!is.na(match(MSnbase::fData(obj)[[mrk]], all_mrk))) #same thing but for all organelle
npr <- length(which(fData(obj)$markers != "unknown"))
m_tit <- "all organelle"
}
#when not mean profile
if(!mean_prof){
.data <- as.data.frame(t(MSnbase::exprs(obj)[i,])) #the data from each protein we selected
.data$fraction <- rownames(.data) #the row are the fraction, le column the proteins
.data <- .data %>% #reorganise the data in order to plot them : Intensity versus Fraction
dplyr::select(fraction, colnames(.data)) %>%
tidyr::gather(key = "prot", value = "value", -fraction)
.data$mark <- fData(obj)[mrk][.data$prot,] #get the organelle for each proteins
if (Interact | one_pr){
g <- ggplot2::ggplot(.data, aes(x=fraction, y=value)) +
ggplot2::geom_line(aes(color = prot, linetype=mark, group = prot)) + #we can differentiate every protein according to their organelle (only in interactive graph)
labs(linetype = "Organelle", color = "Proteins")
}
if (!Interact & !one_pr){
g <- ggplot(.data, aes(x=fraction, y=value)) +
geom_line(aes(color = mark, group = prot)) +
scale_color_manual(values = unlist(PaletteWithoutGrey(.data$mark))) + #differentiate every organelle, set color for each marker with PaletteWithoutGrey
ggplot2::labs(color = "Organelle")
}
#change the title, subtitle and axis names
g <- g +
ggplot2::ggtitle(label= paste("Profile of", m_tit),
subtitle = paste(subt,",", npr, prtx)) +
ggplot2::theme(plot.title = element_text(hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5)) +
ggplot2::xlab(xLab) +
ggplot2::ylab(yLab)
if (one_pr & !is.null(protein)){ #highlight specific proteins
if (!Interact) {
g <- g + gghighlight::gghighlight(!is.na(match(prot, protein)), #the predicate
label_key = prot,
max_highlight = 50,
label_params = list(size = 4, fill = "lightblue", color = "red", alpha =1),
unhighlighted_params = list(size = 0.5)) +
ggplot2::aes(alpha=0.8, size = 1.4) +
ggplot2::guides(size = "none", alpha = "none") #bigger size for profile we want to highlight
}
if (Interact){
g <- g + gghighlight::gghighlight(!is.na(match(prot, protein)),
label_key = prot,
max_highlight = 50,
use_direct_label = FALSE, #ggplotly (for now) can't handle labeling
unhighlighted_params = list(size = 0.5))
}
}
}
#when ploting mean profile
else{
.data <- as.data.frame(MSnbase::exprs(obj)[i,]) #the data from each protein we selected
.data$mark <- fData(obj)[mrk][rownames(.data),] #get the organelle for each proteins
tab <- list()
if (one_pr){
Or <- all_mrk
}
else{
Or <- Organelle
}
for (k in Or){
tab1 <- as.data.frame(
apply(.data[which(.data$mark == k),-ncol(.data)],
2, function(x) mean(x))) #get the profile's mean for each organelle you selected
colnames(tab1) <- k
tab[[k]] <- tab1
}
.data <- do.call(cbind, tab)
.data$fraction <- rownames(.data) #the row are the fraction, le column the proteins
.data <- .data %>% #reorganise the data in order to plot them : Intensity versus Fraction
dplyr::select(fraction, colnames(.data)) %>%
tidyr::gather(key = "mark", value = "value", -fraction)
y <<- .data
g <- ggplot(.data, aes(x=fraction, y=value)) +
geom_line(aes(color = mark, group = mark)) +
scale_color_manual(values = PaletteWithoutGrey(.data$mark)) + #differentiate every organelle, set color for each marker with PaletteWithoutGrey
ggplot2::labs(color = "Organelle")
}
if (Interact){
gI <- plotly::ggplotly(g, tooltip = c("color", "linetype", "group")) %>% #the tooltip is the legend which is shown by the cursor
plotly::layout(hovermode = "closest", clickmode = "select",
margin = list(t = 75),
title = list(text = paste0(paste("Profile of", m_tit), #personalize the title and subtitle
'<br>',
'<sup>',
paste(subt,",", npr, prtx),
'</sup>'
))
)
for (i in 1:length(gI$x$data)){ #change the name of the element of the legend and how they are grouped (here by their organelle)
if (!is.null(gI$x$data[[i]]$name)){
gI$x$data[[i]]$name = gsub("\\)", "", gsub("\\(","",gI$x$data[[i]]$name))
gI$x$data[[i]]$legendgroup = gsub("\\)","", stringr::str_split(gI$x$data[[i]]$legendgroup,",")[[1]][2])
}
if (gI$x$data[[i]]$showlegend == FALSE){
gI$x$data[[i]]$showlegend <- TRUE #show every legend
}
}
return(gI) #the interactive graph
}
else {
return(g)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.