igraph - set node color to categorical vertex attribute

心已入冬 提交于 2021-01-29 20:07:32

问题


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")

回答1:


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")

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),]


来源:https://stackoverflow.com/questions/61758388/igraph-set-node-color-to-categorical-vertex-attribute

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!