R/network_visualization.R

Defines functions initiate_cy plot_intramodular_network plot_tf_network

Documented in initiate_cy plot_intramodular_network plot_tf_network

#' Function to visualize transcription factors regulatory network
#' @description This function integrate R package igraph to visualize consequence
#' of regulatory network analysis
#' @param TFs_list TFs_list generated by \code{\link{network_analysis}}
#' @param layout the layout to display the network, options: 'grid','sphere',
#' 'circle','random'
#' @param group.cols colors for group in network
#' @param title.name the name of the title
#' @param vertex.size size of vertex whose edge numbers are last 25%
#' @param vertex.size.add expansion size of vertex whose edge numbers are
#' last 25%-75% and top25%
#' @param vertex.label.color ertex label color
#' @param edge.label.color edge label color
#' @param legend logic, indicating whether to show the legend
#' @param vertex.label.cex The label size of vertex
#' @param vertex.label.family vertex label family
#' @param frame.color frame.color
#' @param arrow.size arrow size
#' @param arrow.width arrow width
#' @param edge.width edge width
#' @param edge.curved edge curvature
#' @param edge.color edge color. You need to input two colors, first one indicate
#' 'Positive' regulation, second one indicate 'Negative' regulation.
#' @import ggplot2
#' @importFrom igraph E
#' @importFrom igraph V
#' @importFrom igraph layout_on_grid
#' @importFrom igraph layout_on_sphere
#' @importFrom igraph layout_in_circle
#' @importFrom igraph layout_randomly
#' @export
#' @return figure
#' @examples#'
#' load(system.file("extdata", "test_clustering.rda", package = "IReNA"))
#' Kmeans_clustering <- add_ENSID(test_clustering, Spec1 = "Hs")
#' cor0.6 <- get_cor(Kmeans_clustering, Tranfac201803_Hs_MotifTFsF, 0.7, start_column=3)
#' TFs_list <- network_analysis(cor0.6,Kmeans_clustering)
#' plot_tf_network(TFs_list)
plot_tf_network <- function(TFs_list, layout = 'grid', group.cols = NULL,
                            title.name = NULL, vertex.size = 13, vertex.size.add = 3,
                            vertex.label.color = 'black', edge.label.color = 'black'
                            ,legend = TRUE, vertex.label.cex = 0.8,
                            vertex.label.family = 'ArialMT', frame.color = 'white'
                            , arrow.size = 0.2, arrow.width = 0.5, edge.width = 1.8,
                            edge.curved = 0, edge.color = c('#FDD1B0','#B3B3B3')) {
  validInput(TFs_list,'TFs_list','list')
  validInput(vertex.size,'vertex.size','numeric')
  validInput(vertex.size.add,'vertex.size.add','numeric')
  validInput(legend,'legend','logical')
  validInput(vertex.label.cex,'vertex.label.cex','numeric')
  validInput(arrow.size,'arrow.size','numeric')
  validInput(arrow.width,'arrow.width','numeric')
  validInput(edge.width,'edge.width','numeric')
  validInput(edge.curved,'edge.curved','numeric')
  if (length(edge.color)!=2) {
    stop('You should input two colors for edge.color')
  }

  if (is.null(group.cols)) {
    col1 <- c('#67C7C1','#5BA6DA','#FFBF0F','#C067A9','#EF9951','#E56145',
              '#C0C130','#67C1E3','#EF9951','#00BFC4','#AEC7E8','#E56145','#2F4F4F')
  } else {
    col1 <- group.cols
  }
  network <- TFs_list[["TF_network"]]
  network$TFGroup <- as.integer(network$TFGroup)
  network$TargetGroup <- as.integer(network$TargetGroup)
  tfs <- network[, c("TFSymbol", "TFGroup")]
  target <- network[, c("TargetSymbol", "TargetGroup")]
  colnames(target) <- c("TFSymbol", "TFGroup")
  nodes <- rbind(tfs, target)
  edges <- network[, c("TFSymbol", "TargetSymbol", "Regulation", "Correlation")]
  edge_type <- network$Regulation
  colnames(nodes) <- c("name", "type")
  nodes <- nodes[!duplicated(nodes$name), ]
  colnames(edges) <- c("from", "to", "type", "weight")
  g <- igraph::graph_from_data_frame(edges, vertices = nodes, directed = TRUE)
  tf_degree <- as.data.frame(table(network$TFSymbol))
  cut1 <- as.numeric(summary(as.data.frame(table(network$TFSymbol))[,2])[2])
  cut2 <- as.numeric(summary(as.data.frame(table(network$TFSymbol))[,2])[3])
  cut3 <- as.numeric(summary(as.data.frame(table(network$TFSymbol))[,2])[5])
  vertex.size1 <- c()
  for (i in 1:nrow(nodes)){
    if(nodes[i,1] %in% tf_degree[,1]){
      if(tf_degree[tf_degree[,1]==nodes[i,1],][,2] <= cut1) {
        vertex.size1 <- c(vertex.size1, vertex.size)
      }
      else if(tf_degree[tf_degree[,1]==nodes[i,1],][,2] >= cut3) {
        vertex.size1 <- c(vertex.size1, vertex.size + (vertex.size.add)*2)
      }
      else if(tf_degree[tf_degree[,1]==nodes[i,1],][,2] < cut3 &
              tf_degree[tf_degree[,1]==nodes[i,1],][,2] > cut1) {
        vertex.size1 <- c(vertex.size1, vertex.size + vertex.size.add)
      }
    }
    else{vertex.size1 <- c(vertex.size1, vertex.size)
    }
  }
  if (layout == "grid") {
    layout1 <- igraph::layout_on_grid(g)
  } else if (layout == "sphere") {
    layout1 <- igraph::layout_on_sphere(g)
  } else if (layout == "circle") {
    layout1 <- igraph::layout_in_circle(g)
  } else if (layout == "random") {
    layout1 <- igraph::layout_randomly(g)
  } else {
    stop("please input correct layout name")
  }
  edge.color2 <- c()
  for (i in edge_type) {
    if (i == 'Positive') {
      edge.color2 <- c(edge.color2,edge.color[1])
    } else if (i == 'Negative') {
      edge.color2 <- c(edge.color2,edge.color[2])
    }
  }
  edge.start <- igraph::ends(g, es=igraph::E(g), names=FALSE)
  igraph::E(g)$arrow.size <- arrow.size
  igraph::E(g)$arrow.width <- arrow.width
  igraph::E(g)$label.color <- edge.label.color
  igraph::E(g)$color<- edge.color2
  igraph::E(g)$width<- edge.width
  igraph::V(g)$color <- col1[nodes$type]
  igraph::V(g)$size<- vertex.size1
  igraph::V(g)$label.color <- vertex.label.color
  igraph::V(g)$frame.color <- frame.color

  plot(g, layout = layout1, edge.curved = edge.curved, vertex.label.cex =
         vertex.label.cex, layout = layout1,
         vertex.shape='circle', vertex.label.family = vertex.label.family)
  if (legend == TRUE) {

    legend(x = 1.3, y = 1.3, paste0('Module',levels(factor(igraph::V(g)$type))),
           pch = 21, col = "#777777", pt.bg = col1)

  }
  if (!is.null(title.name)) {
    text(0,1.5,title.name, cex = 1.1)
  }
}


#' Function to visualize intramodular regulatory network
#' @description This function integrate R package igraph to visualize consequence
#' of regulatory network analysis
#' @param TFs_list TFs_list generated by \code{\link{network_analysis}}
#' @param enrichment Enrichment analysis results of genes in each module,
#' generated by \code{\link{enrich_module}}. If it is not NULL, when plotting the
#' Intramodular Network, the functions enriched by each module will be plotted
#' in the diagram
#' @param layout the layout to display the network, options: 'grid','sphere',
#' 'circle','random'
#' @param group.cols colors for group in network
#' @param title.name the name of the title
#' @param vertex.size vertex size
#' @param vertex.label.color ertex label color
#' @param edge.label.color edge label color
#' @param legend logic, indicating whether to show the legend
#' @param vertex.label.cex The label size of vertex
#' @param vertex.label.family vertex label family
#' @param frame.color frame.color
#' @param arrow.size arrow size
#' @param arrow.width arrow width
#' @param edge.width edge width
#' @param edge.curved edge curvature
#' @param edge.color edge color. You need to input two colors, first one indicate
#' 'Positive' regulation, second one indicate 'Negative' regulation.
#' @param vertex.label.degree The position of the label in relation to the vertex
#' (This parameter is valid only when the enrichment does not equal null)
#' @param vertex.label.dist Distance between the label and the vertex
#' (This parameter is valid only when the enrichment does not equal null)
#' @import ggplot2
#' @importFrom igraph E
#' @importFrom igraph V
#' @importFrom igraph layout_on_grid
#' @importFrom igraph layout_on_sphere
#' @importFrom igraph layout_in_circle
#' @importFrom igraph layout_randomly
#' @export
#' @return figure
#' @examples#'
#' load(system.file("extdata", "test_clustering.rda", package = "IReNA"))
#' Kmeans_clustering <- add_ENSID(test_clustering, Spec1 = "Hs")
#' cor0.6 <- get_cor(Kmeans_clustering, Tranfac201803_Hs_MotifTFsF, 0.6, start_column=3)
#' TFs_list <- network_analysis(cor0.6,Kmeans_clustering)
#' #enrichment <- enrich_module(Kmeans_cluster_Ens, org.Hs.eg.db, 'KEGG')
#' #plot_intramodular_network(TFs_list,enrichment,layout = 'random')
plot_intramodular_network <- function(TFs_list, enrichment = NULL,layout = 'circle',
                                      group.cols = NULL, title.name = NULL, vertex.size = 25,
                                      vertex.label.color = 'black', edge.label.color = 'black'
                                      ,legend = TRUE, vertex.label.cex = 1.1,
                                      vertex.label.family = 'ArialMT', frame.color = 'white'
                                      , arrow.size = 0.5, arrow.width = 0.8, edge.width = 2.5,
                                      edge.curved = 0, edge.color = c('#FDD1B0','#B3B3B3'),
                                      vertex.label.degree = 0.35, vertex.label.dist = -6) {
  validInput(TFs_list,'TFs_list','list')
  validInput(vertex.size,'vertex.size','numeric')
  validInput(legend,'legend','logical')
  validInput(vertex.label.cex,'vertex.label.cex','numeric')
  validInput(arrow.size,'arrow.size','numeric')
  validInput(arrow.width,'arrow.width','numeric')
  validInput(edge.width,'edge.width','numeric')
  validInput(edge.curved,'edge.curved','numeric')
  if (length(edge.color)!=2) {
    stop('You should input two colors for edge.color')
  }
  validInput(vertex.label.degree,'vertex.label.degree','numeric')
  validInput(vertex.label.dist,'vertex.label.dist','numeric')

  if (is.null(group.cols)) {
    col1 <- c('#67C7C1','#5BA6DA','#FFBF0F','#C067A9','#EF9951','#E56145',
              '#C0C130','#67C1E3','#EF9951','#00BFC4','#AEC7E8','#E56145','#2F4F4F')
  } else {
    col1 <- group.cols
  }
  tf_network <- TFs_list[["TF_network"]]
  tf_max <- c()
  for (i in levels(as.factor(tf_network$TFGroup))) {
    module <- tf_network[tf_network$TFGroup==i,]
    table1 <- as.data.frame(table(module$TFSymbol))
    group_tf <- table1[table1$Freq == max(table1$Freq),]
    tf <- as.character(group_tf[,1])
    tf_max <- c(tf_max, tf)
  }
  network <- TFs_list[["intramodular_network"]]
  tfs <- network[, c("TFGroup", "TFGroup")]
  target <- network[, c("TargetGroup", "TargetGroup")]
  colnames(target) <- c("TFGroup", "TFGroup")
  nodes <- rbind(tfs, target)
  edges <- network[, c("TFGroup", "TargetGroup", "Regulation", "Correlation")]
  edge_type <- network$Regulation
  if (is.null(enrichment)) {
    vertex.label.dist <- 0
    vertex.label.degree <- 0
    for (i in 1:nrow(edges)) {
      name1 <- tf_max[as.integer(edges[i,1])]
      name2 <- tf_max[as.integer(edges[i,2])]
      edges[i,1] <- paste0('Module ',edges[i,1],'\n',name1)
      edges[i,2] <- paste0('Module ',edges[i,2],'\n',name2)
    }
    for (i in 1:nrow(nodes)) {
      name1 <- tf_max[as.integer(nodes[i,1])]
      name2 <- tf_max[as.integer(nodes[i,2])]
      nodes[i,1] <- paste0('Module ',nodes[i,1],'\n',name1)
      nodes[i,2] <- paste0('Module ',nodes[i,2])}
  } else{
    for (i in 1:nrow(edges)) {
      name1 <- tf_max[as.integer(edges[i,1])]
      name2 <- tf_max[as.integer(edges[i,2])]
      edges[i,1] <- paste0('Module ',edges[i,1],'\n','enriched factor: ',name1,
                           '\n','enriched function:','\n',
                           enrichment[enrichment$module == edges[i,1],][1,2])
      edges[i,2] <- paste0('Module ',edges[i,2],'\n','enriched factor: ',name2,
                           '\n','enriched function:','\n',
                           enrichment[enrichment$module == edges[i,2],][1,2])
    }
    for (i in 1:nrow(nodes)) {
      name1 <- tf_max[as.integer(nodes[i,1])]
      name2 <- tf_max[as.integer(nodes[i,2])]
      nodes[i,1] <- paste0('Module ',nodes[i,1],'\n','enriched factor: ',
                           name1,'\n','enriched function:','\n',
                           enrichment[enrichment$module == nodes[i,1],][1,2])
      nodes[i,2] <- paste0('Module ',nodes[i,2])
    }
  }
  colnames(nodes) <- c("name", "type")
  nodes <- nodes[!duplicated(nodes$name), ]
  colnames(edges) <- c("from", "to", "type", "weight")
  g <- igraph::graph_from_data_frame(edges, vertices = nodes, directed = TRUE)
  if (layout == "grid") {
    layout1 <- igraph::layout_on_grid(g)
  } else if (layout == "sphere") {
    layout1 <- igraph::layout_on_sphere(g)
  } else if (layout == "circle") {
    layout1 <- igraph::layout_in_circle(g)
  } else if (layout == "random") {
    layout1 <- igraph::layout_randomly(g)
  } else {
    stop("please input correct layout name")
  }
  edge.color2 <- c()
  for (i in edge_type) {
    if (i == 'Positive') {
      edge.color2 <- c(edge.color2,edge.color[1])
    } else if (i == 'Negative') {
      edge.color2 <- c(edge.color2,edge.color[2])
    }
  }
  edge.start <- igraph::ends(g, es=igraph::E(g), names=FALSE)
  igraph::E(g)$arrow.size <- arrow.size
  igraph::E(g)$arrow.width <- arrow.width
  igraph::E(g)$label.color <- edge.label.color
  igraph::E(g)$color<- edge.color2
  igraph::E(g)$width<- edge.width
  igraph::V(g)$color <- col1[1:length(nodes$type)]
  igraph::V(g)$size<- vertex.size
  igraph::V(g)$label.color <- vertex.label.color
  igraph::V(g)$frame.color <- frame.color

  plot(g, layout = layout1, edge.curved = edge.curved, vertex.label.cex =
         vertex.label.cex, layout = layout1,
         vertex.shape='circle', vertex.label.family = vertex.label.family,
       vertex.label.dist = vertex.label.dist, vertex.label.degree = vertex.label.degree)
  if (legend == TRUE) {
    legend(x = 1.5, y = 1.3, levels(factor(igraph::V(g)$type)), pch = 21,
           col = "#777777", pt.bg = col1)
  }
  if (!is.null(title.name)) {
    text(0,1.5,title.name, cex = 1.1)
  }
}

#' initiating the cytoscape
#' @description Initiate Cytoscape to visualize regulatory network
#' @param TFs_list TFs_list generated by \code{\link{network_analysis}}
#' @param colour vector, indicating colors for border of each node
#' @param type network type, 'TF' indicate TFs network, 'module' indicate
#' intramodular network
#' @param layout1 the layout to display the network, options: "degree-circle",
#' "attributes-layout", "kamada-kawai", "force-directed", "cose", "hierarchical",
#' "attribute-circle", "stacked-node-layout", "circular", "grid"
#' @return Cytoscape visualization
#' @importFrom RCy3 cytoscapePing
#' @importFrom RCy3 cytoscapeVersionInfo
#' @importFrom RCy3 createNetworkFromDataFrames
#' @importFrom RCy3 mapVisualProperty
#' @importFrom RCy3 createVisualStyle
#' @importFrom RCy3 setVisualStyle
#' @importFrom RCy3 layoutNetwork
#' @export
#'
#' @examples \dontrun{
#' initiate_cy(TFs_list, layout1='degree-circle', type='TF')
#' initiate_cy(TFs_list, layout1='grid', type='module')
#' }
initiate_cy <- function(TFs_list, colour = NULL, type = "TF", layout1 = "degree-circle") {
  RCy3::cytoscapePing()
  RCy3::cytoscapeVersionInfo()
  if (type == "TF") {
    network <- TFs_list[["TF_network"]]
    tfs <- network[, c("TFSymbol", "TFGroup")]
    target <- network[, c("TargetSymbol", "TargetGroup")]
    colnames(target) <- c("TFSymbol", "TFGroup")
    nodes <- rbind(tfs, target)
    edges <- network[, c("TFSymbol", "TargetSymbol", "Regulation", "Correlation")]
  } else if (type == "module") {
    network <- TFs_list[["intramodular_network"]]
    tfs <- network[, c("TFGroup", "TFGroup")]
    target <- network[, c("TargetGroup", "TargetGroup")]
    colnames(target) <- c("TFGroup", "TFGroup")
    nodes <- rbind(tfs, target)
    edges <- network[, c("TFGroup", "TargetGroup", "Regulation", "Correlation")]
    edges$TFGroup <- as.character(edges$TFGroup)
    edges$TargetGroup <- as.character(edges$TargetGroup)
    nodes$TFGroup <- as.character(nodes$TFGroup)
  }
  colnames(nodes) <- c("id", "group")
  nodes <- nodes[!duplicated(nodes$id), ]
  colnames(edges) <- c("source", "target", "interaction", "weight")
  RCy3::createNetworkFromDataFrames(nodes, edges, title = "my first network",
                                    collection = "DataFrame Example")
  style.name <- "network1"
  if (is.null(colour)) {
    col1 <- c('#67C1E3','#EF9951','#00BFC4','#AEC7E8','#C067A9','#E56145','#2F4F4F')
  } else {
    col1 <- colour
  }
  defaults <- list(
    NODE_SHAPE = "BioPAX",
    NODE_SIZE = 120,
    EDGE_TRANSPARENCY = 120,
    NODE_LABEL_FONT_SIZE = 29,
    NODE_FILL_COLOR = "White"
  )
  nodeLabels <- RCy3::mapVisualProperty("node label", "id", "p")
  nodeborder <- RCy3::mapVisualProperty(
    "Node Border Paint", "group", "d", levels(as.factor(network$TFGroup)),
    col1
  )
  arrowShapes <- RCy3::mapVisualProperty("Edge Target Arrow Shape", "interaction",
                                         "d", levels(as.factor(network$Regulation)),
                                         c("Arrow", "T", "None"))
  edgeWidth <- RCy3::mapVisualProperty("edge width", "weight", "p")
  nodeFills <- RCy3::mapVisualProperty("Node Fill Color", "group", "p")
  RCy3::createVisualStyle(style.name, defaults, list(nodeLabels, nodeborder,
                                                     arrowShapes, edgeWidth, nodeFills))
  RCy3::setVisualStyle(style.name)
  RCy3::layoutNetwork(layout1)
}
jiang-junyao/IReNA documentation built on May 17, 2024, 12:29 a.m.