Search code examples
rigraphgraph-visualization

iGraph (R) - conditionally changing the color or weight of an edge


I'm trying to change the color of nodes in a graph based on the value of a flag that corresponds to a particular node. See the edgelist HAVE below for example:

ego friend  realfriend  resources
Joe Jim              1          2
Joe Jon              1          1
Joe James            1          5
Sam Jeff             1          2
Sam Stephanie        1          3
Sam Joe              1          1
Sam Jim              1          1
Bob Dylan            0          1
Bob Jim              1          4

Dylan is an imaginary friend, so I want the node representing him (and other imaginary friends) to be different from realfriend = 1. I turn HAVE into a plot as follows:

test <- graph.data.frame(HAVE, directed=F)
plot(test, vertex.size=degree(test))

But when I try to make nodes appear as different colors based on the value for realfriend, the graph does not produce any change in color:

colrs <- c("red", "blue")
V(test)$color <- colrs[V(test)$realfriend]

Any idea why this would not work?


Solution

  • The data for the graph is shown at the end.

    There are a lot of things that need to be adjusted to get what you want. First, as I noted in the comments, as you constructed it, realfriend is a property of the edges, not the vertices. To be able to color the vertices, you need a property of the vertices. I believe that what you meant was that everyone listed in HAVE$ego (first column) is real. HAVE$realfriend is an indicator of whether or not HAVE$friend (second column) is real. So we need to transfer this from the edges to the vertices. Then we can use something like your code to assign colors for the vertices, but there are other small problems to fix. You use V(test)$realfriend to index into the list of colors. But (once we create it) V(test)$realfriend takes on the values 0 or 1. There is no color 0. We need colors 1 or 2, so I add one to V(test)$realfriend when using it as an index into the colors. Also, you plot some of the vertices very small, so it is hard to tell what color they are. I kept the size proportional to the degree, but made the vertices much bigger. So, putting this all together:

    library(igraph)
    test <- graph.data.frame(HAVE, directed=F)
    
    ## label the vertices with reality
    for(i in 1:ecount(test)) {
        E = ends(test, E(test)[i])
        V(test)[E[1]]$realfriend = 1
        V(test)[E[2]]$realfriend = HAVE$realfriend[i]
    }
    
    colrs <- c("red", "blue")
    V(test)$color <- colrs[V(test)$realfriend+1]
    
    plot(test, vertex.size=degree(test)*6)
    

    Graph with colored vertices

    Notice that Dylan came out red and the rest are blue.

    Data

    HAVE = read.table(text="ego friend  realfriend  resources
    Joe Jim              1          2
    Joe Jon              1          1
    Joe James            1          5
    Sam Jeff             1          2
    Sam Stephanie        1          3
    Sam Joe              1          1
    Sam Jim              1          1
    Bob Dylan            0          1
    Bob Jim              1          4",
    header=TRUE)