I'm trying to plot a network
(a protein-protein interaction graph as an R igraph
object), which is moderately large in size (111 nodes with 929 edges), so I'm trying to find a reasonable way of labeling the nodes, which are either the protein IDs or the names of their encoding genes, where in either case these labels are several characters long.
Here's the code to obtain the protein-protein interaction 'igraph' object:
library(STRINGdb)
string.db <- STRINGdb$new(version="11.5",species=9606,score_threshold=200,input_directory="")
string.graph <- string.db$get_graph()
igraph::V(string.graph)$name <- gsub("^9606\\.","",igraph::V(string.graph)$name)
string.graph
is the entire graph and below I subset it to keep only the nodes connected to a pair of proteins of interest:
protein1 <- "ENSP00000475261"
protein2 <- "ENSP00000360829"
neighbors1 <- igraph::neighbors(graph = string.graph, v = protein1, mode = "all")
neighbors1 <- neighbors1[which(!is.na(names(neighbors1)))]
neighbors2 <- igraph::neighbors(graph = string.graph, v = protein2, mode = "all")
neighbors2 <- neighbors2[which(!is.na(names(neighbors2)))]
all.neighbors <- unique(c(neighbors1, neighbors2))
string.subgraph.vs <- igraph::V(string.graph)[name %in% c(names(all.neighbors), protein1, protein2)]
string.subgraph.vs.list <- igraph::ego(string.graph, order = 1, nodes = string.subgraph.vs, mode = "all", mindist = 0)
string.subgraph <- igraph::induced_subgraph(string.graph, unlist(string.subgraph.vs.list))
nodes.df <- data.frame(id = names(igraph::V(string.subgraph))) %>%
unique() %>% dplyr::filter(id %in% c(names(all.neighbors), protein1, protein2)) %>%
dplyr::mutate(size = 1, color = NA)
nodes.df$color[which(nodes.df$id %in% names(neighbors1) & !(nodes.df$id %in% names(neighbors2)))] <- "cornflowerblue"
nodes.df$color[which(nodes.df$id %in% names(neighbors2) & !(nodes.df$id %in% names(neighbors1)))] <- "#ee2400"
nodes.df$color[which(nodes.df$id %in% names(neighbors1) & nodes.df$id %in% names(neighbors2))] <- "darkorchid1"
nodes.df$color[which(nodes.df$id == protein1)] <- "cornflowerblue"
nodes.df$color[which(nodes.df$id == protein2)] <- "#ee2400"
nodes.df$size[which(nodes.df$id == protein1)] <- 3
nodes.df$size[which(nodes.df$id == protein2)] <- 3
edges.df <- as.data.frame(igraph::get.edgelist(string.subgraph)) %>%
dplyr::rename(from = V1, to = V2) %>% unique() %>%
dplyr::filter(from %in% c(names(all.neighbors), protein1, protein2) & to %in% c(names(all.neighbors), protein1, protein2))
new.string.subgraph <- igraph::graph_from_data_frame(d = edges.df, directed = F, vertices = nodes.df)
A bit cumbersome but I followed this blog for subsetting an igraph
object.
If I plot it, using R
's ggplot2
and ggnetwork
packages, adding the node labels:
ggplot(new.string.subgraph, aes(x = x, y = y, xend = xend, yend = yend)) +
ggnetwork::geom_edges(color = "grey50", alpha = 0.1) +
ggnetwork::geom_nodes(color = igraph::vertex_attr(new.string.subgraph)$color, size = igraph::vertex_attr(new.string.subgraph)$size) +
ggnetwork::geom_nodetext(aes(label = name)) +
ggnetwork::theme_blank()
The outcome is quite crowded with the node labels:
Relative to what it looks like without the node labels:
ggplot(new.string.subgraph, aes(x = x, y = y, xend = xend, yend = yend)) +
ggnetwork::geom_edges(color = "grey50", alpha = 0.1) +
ggnetwork::geom_nodes(color = igraph::vertex_attr(new.string.subgraph)$color, size = igraph::vertex_attr(new.string.subgraph)$size) +
ggnetwork::theme_blank()
BTW, I'm hoping that the set.seed(1)
indeed guarantees that the plot is reproducible.
So, I thought perhaps I'd use plotly
(plotly::ggplotly()
) to be able to see the node labels as a hover-over feature. But, all I'm seeing are the x and y coordinates as hover-over and if I assign label
to the tooltip
parameter of plotly::ggplotly
I don't see any hover-over information at all.
Any idea how to get plotly
to display the node labels without actually seeing them in the plot?
I wasn't able to load the STRINGdb
package for the latest version of R (4.3.0). However, have you tried modifying your plotly
object using plotly::style
? I'm assuming it would look something like the following:
p <- ggplot(new.string.subgraph, aes(x = x, y = y, xend = xend, yend = yend)) +
ggnetwork::geom_edges(color = "grey50", alpha = 0.1) +
ggnetwork::geom_nodes(color = igraph::vertex_attr(new.string.subgraph)$color, size = igraph::vertex_attr(new.string.subgraph)$size) +
ggnetwork::theme_blank()
p <- p %>% style(hoverinfo = "name")
ggplotly(p)
You may have to play around with the style arguments. See this plotly page for more details.