Search code examples
rvisualizationigraphvisnetwork

how to dynamically color a node according to the groups it belongs to?


So, here we go. I have a network with several nodes. Each node may belong to different groups (see my idea below).

This is a toy example, with an edge list:

"from","to"
"RB1","CDK2"
"CDK2","CDKN1B"
"RB1","CDK4"
"PDPK1","RPS6KB1"
"PDPK1","PKN2"
"CDKN1B","CDK4"
"PKN2","CDK4"

and a nodes table with one group only (stat column):

name,stat
RB1,mixed
CDK2,up
CDKN1B,up
CDK4,up
PDPK1,up
RPS6KB1,up
PKN2,down

and then the code that generate the network with the attribute stat, that is currently used to colour code the nodes, according to which stat the user selected:

library(tidyverse)
library(igraph)
library(visNetwork)

edgelist  <- read.csv("edges_mod.csv")
nodes <- read.csv("nodes_mod.csv")

g <- graph_from_data_frame(edgelist,directed=F,vertices=nodes)

V(g)$color  <- ifelse(V(g)$stat == "up", "red",ifelse(V(g)$stat == "down","blue","yellow"))

data <- toVisNetworkData(g)


visNetwork(nodes=data$nodes, edges=data$edges, width="100%") %>%
    visEdges(color="black") %>%
    visIgraphLayout(layout="layout_with_kk") %>%
    visOptions(selectedBy= "stat")

The problem here is: what if a node may belong to several stats? I see two main options here:

I can create the same data frame as above but with multiple stat columns and colour-code the nodes according to the column which is selected. I was thinking about a [0-1] column in which the nodes that belong to that set are labelled with 1 and will be coloured (or ON) in the network while, the nodes that do not belong to that set will be labelled as 0 (and will be OFF).

name,statZero,statOne,statTwo
RB1,1,1,0
CDK2,1,1,0
CDKN1B,1,0,0
CDK4,1,1,0
PDPK1,1,1,1
RPS6KB1,0,0,0
PKN2,1,0,0

OR, I can create the same data frame as above with the stat columns containing a list of sets but I don't really see how it may work

Ideas on how to colour-code the nodes belonging to different sets? How can I deal with this option visOptions(selectedBy= "stat")?

EDIT:

I know that visOption has several possibilities for selectedBy. I'm trying to figure out how it applies to my needs!


Solution

  • Please have a look at visOptions, argument selectedBy and set multiple=TRUE.

    So I added another attribute on your nodes as cluster

    Let nodes be:

    name,stat,cluster
    RB1,mixed,alpha
    CDK2,up,alpha
    CDKN1B,up,alpha
    CDK4,up,beta
    PDPK1,up,beta
    RPS6KB1,up,beta
    PKN2,down,alpha
    
    

    and edges as you defined,

    Then:

    library(tidyverse)
    library(igraph)
    library(visNetwork)
    
    edgelist  <- read.csv("edge.csv")
    nodes <- read.csv("node.csv")
    
    g <- graph_from_data_frame(edgelist,directed=F,vertices=nodes)
    
    V(g)$color  <- ifelse(V(g)$stat == "up", "red",ifelse(V(g)$stat == "down","blue","yellow"))
    V(g)$groups <- paste(V(g)$stat, V(g)$cluster, sep=",")
    
    data <- toVisNetworkData(g)
    
    
    visNetwork(nodes=data$nodes, edges=data$edges, width="100%") %>%
        visEdges(color="black") %>%
        visIgraphLayout(layout="layout_with_kk") %>%
        visOptions(selectedBy= list(variable="groups",multiple=T))
    
    

    This should reproduce what you want to achieve!