Nothing
#' @title Plotly Log2FC Network Plot
#'
#' @description This function returns a list with interactive
#' networkplot based on log2 fold change data.
#'
#' @param metalyzer_se A MetAlyzer Object
#' @param q_value A numeric value specifying the cutoff for q-value
#' @param metabolite_node_size The text size of the metabolite Nodes
#' @param connection_width The line width of connections between metabolites
#' @param pathway_text_size The text size of pathway annotations
#' @param pathway_width The line width of pathway-specific connection coloring
#' @param plot_height The height of the Plot in pixel [px]
#' @return plotly object
#'
#' @import dplyr
#' @import viridis
#' @import viridisLite
#' @import SummarizedExperiment
#' @importFrom rlang .data
#' @importFrom stats na.omit
#' @importFrom plotly plot_ly add_annotations layout
#' @export
#'
#' @examples
#' metalyzer_se <- MetAlyzer_dataset(file_path = example_mutation_data_xl())
#' metalyzer_se <- filterMetabolites(
#' metalyzer_se,
#' drop_metabolites = "Metabolism Indicators"
#' )
#' metalyzer_se <- renameMetaData(
#' metalyzer_se,
#' Mutant_Control = "Sample Description"
#' )
#'
#' metalyzer_se <- calculate_log2FC(
#' metalyzer_se,
#' categorical = "Mutant_Control",
#' impute_perc_of_min = 0.2,
#' impute_NA = FALSE
#' )
#'
#' p_network <- plotly_network(metalyzer_se, q_value = 0.05)
plotly_network <- function(metalyzer_se,
q_value=0.05,
metabolite_node_size=11,
connection_width=1.25,
pathway_text_size=20,
pathway_width=10,
plot_height=800) {
log2FC_df <- metalyzer_se@metadata$log2FC
pathway_file <- MetAlyzer::pathway()
## Read network nodes, edges and annotations
pathways <- read_named_region(pathway_file, "Pathways_Header")
invalid_annotations <- which(
is.na(pathways$Label) |
duplicated(pathways$Label) |
is.na(pathways$x) |
is.na(pathways$y) |
is.na(pathways$Color)
)
if (length(invalid_annotations) > 0) {
# print warning and remove
cat("Warning: Removing", length(invalid_annotations), "invalid pathways.\n")
pathways <- pathways[-invalid_annotations, ]
}
rownames(pathways) <- pathways$Label
nodes <- read_named_region(pathway_file, "Metabolites_Header")
nodes$Pathway[is.na(nodes$Pathway)] <- ""
invalid_nodes <- which(
is.na(nodes$Label) |
duplicated(nodes$Label) |
is.na(nodes$x) |
is.na(nodes$y) |
!nodes$Pathway %in% c(rownames(pathways), "")
)
if (length(invalid_nodes) > 0) {
# print warning and remove
cat("Warning: Removing", length(invalid_nodes), "invalid nodes.\n")
nodes <- nodes[-invalid_nodes, ]
}
rownames(nodes) <- nodes$Label
# Remove #1 at the end
nodes$Label <- gsub("#[0-9]+", "", nodes$Label)
edges <- read_named_region(pathway_file, "Connections_Header")
invalid_edges <- which(
!edges$Node1 %in% rownames(nodes) |
!edges$Node2 %in% rownames(nodes) |
edges$Node1 == edges$Node2
)
if (length(invalid_edges) > 0) {
# print warning and remove
cat("Warning: Removing", length(invalid_edges), "invalid connections.\n")
edges <- edges[-invalid_edges, ]
}
edges$x_start <- nodes[edges$Node1, "x"]
edges$y_start <- nodes[edges$Node1, "y"]
edges$x_end <- nodes[edges$Node2, "x"]
edges$y_end <- nodes[edges$Node2, "y"]
edges$Color <- sapply(rownames(edges), function(rowname) {
from <- edges[rowname, "Node1"]
to <- edges[rowname, "Node2"]
from_pathway <- nodes[from, "Pathway"]
to_pathway <- nodes[to, "Pathway"]
color <- NA
if (from_pathway == to_pathway & from_pathway != "") {
color <- pathways[from_pathway, "Color"]
}
return(color)
})
## Add log2FC to nodes_df
signif_df <- filter(log2FC_df,
!is.na(.data$log2FC),
!is.na(.data$qval),
.data$qval <= q_value)
nodes$FC_thresh <- sapply(strsplit(nodes$Metabolites, ";"), function(m_vec) {
tmp_df <- filter(signif_df, .data$Metabolite %in% m_vec)
if (nrow(tmp_df) > 0) {
# Alteast 1 significantly changed
l2fc <- sum(tmp_df$log2FC) / nrow(tmp_df)
} else if (any(m_vec %in% log2FC_df$Metabolite)) {
# Not significantly changed but measured
l2fc <- 0
} else {
# Not measured
l2fc <- NA
}
return(l2fc)
})
## Add p-value to nodes_df
nodes$q_value <- sapply(strsplit(nodes$Metabolites, ";"), function(m_vec) {
tmp_df <- filter(signif_df, .data$Metabolite %in% m_vec)
if (nrow(tmp_df) > 0) {
# Alteast 1 significantly changed
qval <- sum(tmp_df$qval) / nrow(tmp_df)
} else if (any(m_vec %in% log2FC_df$Metabolite)) {
# Not significantly changed but measured
qval <- sum(log2FC_df$qval[which(log2FC_df$Metabolite %in% m_vec)]) / length(m_vec)
} else {
# Not measured
qval <- NA
}
return(qval)
})
## Draw network
# Create a plot of the network using ggplotly
# Preparing Hexcodes for Annotation Colors
nodes$color <- sapply(nodes$FC_thresh, function(value) {
if (is.na(value)) {
return("grey")
} else {
# Using the viridis color scale, adjust 'option' based on your preference
color_scale <- viridis(10, option = "D")
nodes_range <- na.omit(nodes$FC_thresh)
color_index <- findInterval(value, seq(min(nodes_range), max(nodes_range)+0.1, length.out = length(color_scale) + 1))
return(color_scale[color_index])
}
})
# Prepare the Edges List
area_shapes <- list()
for (i in seq_along(edges$Color)) {
if (is.na(edges$Color[i])) {
edges$Color[i] <- "white" # Assign edges without pathway white
}
}
# Create background of edges
for (i in 1:nrow(edges)) {
area_shape <- list(
type = "line",
x0 = edges$x_start[i],
y0 = edges$y_start[i],
x1 = edges$x_end[i],
y1 = edges$y_end[i],
line = list(
color = edges$Color[i],
width = pathway_width
)
)
area_shapes[[i]] <- area_shape
}
# Create the edges
edge_shapes <- list()
for (i in 1:nrow(edges)) {
edge_shape <- list(
type = "line",
x0 = edges$x_start[i],
y0 = edges$y_start[i],
x1 = edges$x_end[i],
y1 = edges$y_end[i],
line = list(
color = "grey",
width = connection_width
)
)
edge_shapes[[i]] <- edge_shape
}
edges_area_combined <- c(area_shapes, edge_shapes)
# Create the nodes
network <- plot_ly(nodes,
x = nodes$x,
y = nodes$y,
type = "scatter",
mode = "markers",
marker = list(color = nodes$FC_thresh,
colorbar = list(title = ""),
colorscale='Viridis',
showscale = TRUE),
height = plot_height)
# Add the edges
p_network <- layout(
network,
title = 'Log2(FC) with FDR Correction',
shapes = edges_area_combined,
xaxis = list(title = "", showgrid = FALSE, showticklabels = FALSE, zeroline = FALSE),
yaxis = list(title = "", showgrid = FALSE, showticklabels = FALSE, zeroline = FALSE),
hovermode = FALSE)
# Add annotations over the nodes
for (i in 1:nrow(nodes)) {
p_network <- p_network %>% add_annotations(
text = nodes$Label[i],
x = nodes$x[i],
y = nodes$y[i],
arrowhead = 0,
font = list(size = metabolite_node_size, color = "white"),
ax = 0,
ay = 0,
bgcolor = nodes$color[i],
opacity = 1,
hovertext = paste0("log2 Fold Change: ", round(nodes$FC_thresh[i], 5),
"\nPathway: ", nodes$Pathway[i],
"\nadj. p-value: ", round(nodes$q_value[i], 5))
)
}
# Add annotations for the pathways
for (i in 1:nrow(pathways)) {
p_network <- p_network %>% add_annotations(
text = pathways$Pathway[i],
x = pathways$x[i],
y = pathways$y[i],
xref = "x",
yref = "y",
showarrow = FALSE,
font = list(size = pathway_text_size, color = pathways$Color[i])
)
}
return(p_network)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.