Vertex Labels in igraph R

14,747

Solution 1

You can specify the labels like this:

 library(igraph)
gg <- graph.data.frame(
  links,directed=FALSE, 
  vertices = rbind(
    setNames(links[,c(1,4)],c("id","label")), 
    setNames(links[,c(2,5)], c("id","label"))))
plot(gg, vertex.color = 'lightblue', edge.label=links$value, 
     vertex.size=1, edge.color="darkgreen", 
     vertex.label.font=1, edge.label.font =1, edge.label.cex = 1, 
     vertex.label.cex = 2 )

enter image description here

You could also pass

merge(rbind(
    setNames(links[,c(1,4)],c("id","label")), 
    setNames(links[,c(2,5)], c("id","label"))), 
    nodes, 
    by.x="label", by.y="name")

to the vertices argument if you needed the other node attributes.

Data:

 links <- read.table(header=T, text="
  source target  value sourceID targetID
1      3      4 0.6245  1450552  1519842
2      6      8 0.5723  2607133  3051992
3      9      7 0.7150  3101536  3025831
4      0      1 0.7695   401517   425784
5      2      5 0.5535  1045501  2258363")

 nodes <- read.table(header=T, text="
      name group size
1   401517     1    8
2   425784     1    8
3  1045501     1    8
4  1450552     1    8
5  1519842     1    8
6  2258363     1    8
7  2607133     1    8
8  3025831     1    8
9  3051992     1    8
10 3101536     1    8")

Solution 2

It appears I was able to repurpose the answer to this question to achieve this.

r igraph - how to add labels to vertices based on vertex id

The key was to use the vertex.label attribute within plot() and a select a sliced subset of nodes$names.

For our index we can use the ordered default labels returned in igraph automatically. To extract these, you can type V(gg)$names.

Within plot(gg) we can then write:

vertex.label = nodes[c(as.numeric(V(gg)$name)+1),]$name
# 1 Convert to numeric
# 2 Add 1 for offset between proxy links index and nodes index
# 3 Select subset of nodes with above as row index. Return name column

As full code:

gg <- graph.data.frame(links,directed=FALSE)
plot(gg, vertex.color = 'lightblue', edge.label=links$value, vertex.size=1, edge.color="darkgreen", 
     vertex.label.font=1, edge.label.font =1, edge.label.cex = 1, 
     vertex.label.cex = 2, vertex.label = nodes[c(as.numeric(V(gg)$name)+1),]$name)

With the data above, this gave:

enter image description here

Solution 3

The easiest solution would be to reorder the columns of links, because according to the documentation:

"If vertices is NULL, then the first two columns of d are used as a symbolic edge list and additional columns as edge attributes."

Hence, your code will give the correct output after running:

links <- links[,c(4,5,3)]
Share:
14,747
Chuck
Author by

Chuck

I'd rather be doing Physics

Updated on August 18, 2022

Comments

  • Chuck
    Chuck almost 2 years

    I am using igraph to plot a non directed force network.

    I have a dataframe of nodes and links as follows:

    > links
      source target  value sourceID targetID
    1      3      4 0.6245  1450552  1519842
    2      6      8 0.5723  2607133  3051992
    3      9      7 0.7150  3101536  3025831
    4      0      1 0.7695   401517   425784
    5      2      5 0.5535  1045501  2258363
    
    > nodes
          name group size
    1   401517     1    8
    2   425784     1    8
    3  1045501     1    8
    4  1450552     1    8
    5  1519842     1    8
    6  2258363     1    8
    7  2607133     1    8
    8  3025831     1    8
    9  3051992     1    8
    10 3101536     1    8
    

    I plot these using igraph as follows:

    gg <- graph.data.frame(links,directed=FALSE)
    plot(gg, vertex.color = 'lightblue', edge.label=links$value, vertex.size=1, edge.color="darkgreen", 
         vertex.label.font=1, edge.label.font =1, edge.label.cex = 1, 
         vertex.label.cex = 2 )
    

    enter image description here

    On this plot, igraph has used the proxy indexes for source and target as vertex labels.

    I want to use the real ID's, in my links table expressed as sourceID and targetID.

    So, for:

      source target  value sourceID targetID
    1      3      4 0.6245  1450552  1519842
    

    This would show as:

    (1450552) ----- 0.6245 ----- (1519842)
    

    Instead of:

          (3) ----- 0.6245 ----- (4)
    

    (Note that the proxy indexes are zero indexed in the links dataframe, and one indexed in the nodes dataframe. This offset by 1 is necessary for igraph plotting).

    I know I need to somehow match or map the proxy indexes to their corresponding name within the nodes dataframe. However, I am at a loss as I do no not know the order in which igraph plots labels.

    How can I achieve this?

    I have consulted the following questions to no avail:

    Vertex Labels in igraph with R how to specify the labels of vertices in R R igraph rename vertices

  • Chuck
    Chuck about 7 years
    Thank you for your answer. Really useful. When you say you could pass ... to the vertices argument what exactly do you mean? Do you mean to set vertex.attr = merge....?
  • lukeA
    lukeA about 7 years
    I meant graph.data.frame(..., vertices = merge(...)).
  • Chuck
    Chuck about 7 years
    Excellent, much appreciated.
  • Chuck
    Chuck about 7 years
    I've accepted your answer as, even though I used a different method, I believe yours has the wider use case and provides more informatory benefit. Thanks again, and have a nice day :)