0

I have network g.8 of 24 nodes, and i have set a vertex attribute "country" to for the nodes. I'm trying to set the vertex colors to match the vertex attribute country (n = 10), but the network comes out where nodes have no colour. I get the right colour for the legend though.

EDIT: I have managed to get the nodes coloured, but they don't match the colours on the legend at all.

The data looks like this:

nodes Id Label Country
Degree
1 Urabenos Urabenos Colombia
4 2 Sinaloa Cartel Sinaloa Cartel Mexico
16 3 Los Zetas Los Zetas Mexico
8 4 Norte del Valle Cartel Norte del Valle Cartel Colombia
2 5 Cosa Nostra Cosa Nostra Italy
4 6 NDrangheta NDrangheta Italy
8 7 14K 14K China
6 8 Chinese Triads Chinese Triads China
2 9 Sun yee on Sun yee on China
4 10 MS-13 MS-13 United States
4

… with 14 more rows

edges Source Target Type Label
1 14K
Sinaloa Cartel Undirected Drug Trafficking 2 14K
Sun yee on Undirected Drug trafficking 3 14K
Wo Shing Wo Undirected Unspecified 4 Beltran-Leyva Cartel The Juarez Cartel Undirected New Edge - Association 5 Beltran-Leyva Cartel Los Zetas
Undirected New Edge - Association 6 Bonnano Family
NDrangheta Undirected New Edge - Drug Trafficking 7 Clerkenwell Crime Syndicate Russian Mafia Undirected New Edge - Association 8 Cosa Nostra Sinaloa Cartel
Undirected Drug Trafficking 9 Cosa Nostra
NDrangheta Undirected New Edge - Association 10 First Capital Command Tahvili Group Undirected New Edge - Drug Trafficking

graph + attr: name (v/c), Label (v/c), Country (v/c), Degree (v/n), Type (e/c), Label (e/c) + edges from 9f46a4b (vertex names): 1 Sinaloa Cartel --14K [2] 14K --Sun yee on [3] 14K
--Wo Shing Wo [4] Beltran-Leyva Cartel --The Juarez Cartel [5] Los Zetas --Beltran-Leyva Cartel
[6] NDrangheta --Bonnano Family [7] Russian Mafia --Clerkenwell Crime Syndicate [8] Sinaloa Cartel
--Cosa Nostra
+ ... omitted several edges

My Code so far:

g.8 <- graph_from_data_frame(d=edges.8, vertices=nodes.8, 
    directed=FALSE)


par(mar=c(0,0,0,0))

plot(g.8)

set_vertex_attr(g.8, "country", index = V(g.8), 
as.character(nodes.8$Country))
colrs <- brewer.pal(10, "Set3")
V(g.8)$color <- colrs[V(g.8)$Country]
plot(g.8, vertex.color=colrs,
vertex.label.cex = .75,
edge.label = edges.8$Label,
edge.label.cex = .5,
edge.label.color = "darkgrey") 


 #plot legend for node colors
     legend("topright", c("Brazil","Canada", "China", "Colombia", 
     "Italy", "Japan", "Mexico", "Russia", "UK", "US"), 
     pch=21,col="#777777", pt.bg=colrs, pt.cex=2, cex=.6, bty="n", 
      ncol=1,)

EDIT:

Changed the code according to the great advice given. The color map works, but the vertex colors are still random.

# create a color map
col <- data.frame(Country = unique(nodes.8$Country), 
stringsAsFactors = F)
col$color <- brewer.pal(nrow(col), "Set3")
col

# attach the colors to the nodes data.frame
nodes.8$color <- col$color[match(nodes.8$Country, col$Country)]
nodes.8$color <- col$color[match(nodes.8$Country, col$Country)]

# igraph object
g.8 <- graph_from_data_frame(edges.8,
                       vertices=nodes.8, 
                       directed=FALSE)


plot(g.8,
     vertex.label.cex = .75,
     edge.label.cex = .5,
     edge.label.color = "darkgrey",
     vertex.color = col$color) 
     legend("topright", legend = col$Country, pt.bg=col$color, 
     bty="n",
       pch=21, col="#777777")
nasiZ
  • 3
  • 3
  • have a look here https://stackoverflow.com/questions/61596647/match-vertex-and-edge-color-in-igraph/61598316#61598316 – desval May 12 '20 at 18:34
  • also, it would be great if you could share your data using ```dput``` so that your example is reproducible https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – desval May 12 '20 at 18:40
  • I'll have a look, thank you! – nasiZ May 12 '20 at 20:50
  • Hi @desval I tried to share the data, but didn't work. But I've made edits to my post, with more details and glimpse of what the data looks like. I got colours to my nodes, but they don't match the legend, or the column in the data.frame. – nasiZ May 12 '20 at 22:04
  • I am pretty sure that is not the output of dput, for the next questions maybe try to follow the guidelines in the link ;) – desval May 13 '20 at 06:52
  • @desval sorry about that, I'm brand new to stackoverflow, trying to learn! – nasiZ May 13 '20 at 08:50
  • You should leave out ````vertex.color = col$color````, because it is already in the nodes data.frame and therefore in the igraph object. Plot uses by default the attribute color of the nodes data. For sharing the data, if it isnt too big, just paste the output of ````dput(nodes.8)```` into your questions. Same thing for the edges. – desval May 13 '20 at 08:54

1 Answers1

5

One possibility is to create a map within unique values of the variable Country and the colors you want to use. You can use this map to add colors to the data.frame before you create the i.graph object, so that colors are displayed by default. Then you can use this map for the legend:

library(igraph)
library(RColorBrewer)

# create a color map
col <- data.frame(Country = unique(nodes$Country), stringsAsFactors = F)
col$color <- brewer.pal(nrow(col), "Set3")

# attach the colors to the nodes data.frame
nodes$color <- col$color[match(nodes$Country, col$Country)]

# igraph object
g <- graph_from_data_frame(edges,
                           vertices=nodes, 
                             directed=FALSE)

# check attributes
# each node has a color, which matches the country, it will be used by plot
vertex_attr(g)
$name
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

$Label
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

$Country
 [1] "Italy" "Italy" "Italy" "US"    "Italy" "US"    "US"    "US"    "Italy" "China"

$color
 [1] "#8DD3C7" "#8DD3C7" "#8DD3C7" "#FFFFB3" "#8DD3C7" "#FFFFB3" "#FFFFB3" "#FFFFB3" "#8DD3C7" "#BEBADA"


# plot
plot(g,
   # vertex.color = V(g)$color, # this is added by default, no need to include it
     vertex.label.cex = .75,
     edge.label.cex = .5,
     edge.label.color = "darkgrey") 
legend("topright", legend = col$Country, pt.bg=col$color, bty="n",
       pch=21, col="#777777")

enter image description here

Data

set.seed(123)
nodes <- data.frame(Id = letters[1:10],
                    Label = letters[1:10],
                    Country = sample(c("China", "US", "Italy"), 10, replace = T))

edges <- data.frame(t(combn(letters[1:10], 2, simplify = T)))
names(edges) <- c("Source","Target")
edges <- edges[sample(1:nrow(edges), 25),]
desval
  • 2,345
  • 2
  • 16
  • 23
  • Hi @desval thank you! I tried your suggested code, and the produced color map works, and is correct. But for some reason the color of the nodes are still random, and don't correspond to the data. I'll add an edit with the new code and output. – nasiZ May 13 '20 at 08:40
  • in your code you write over the right colors! Either drop ````vertex.color = col$color```` or use ````vertex.color = V(g)$color ```` – desval May 13 '20 at 09:22