Trong igraph
, sau khi áp dụng thuật toán mô-đun hóa để tìm biểu đồ cộng đồng, tôi muốn vẽ bố cục mạng rõ ràng giúp hiển thị các cộng đồng riêng biệt và kết nối của chúng. Giống như "bố cục thuộc tính nhóm" trong Cytoscape: tôi muốn hiển thị các thành viên của mỗi nhóm/cộng đồng gần nhau và giữ khoảng cách giữa các nhóm/cộng đồng. Tôi không thể tìm thấy bất kỳ chức năng nào trong số igraph
cung cấp tính năng này ra khỏi hộp. Trong khi đăng câu hỏi này tôi đã phát hiện ra một giải pháp d.i.y đơn giản, tôi sẽ đăng nó như một câu trả lời. Nhưng tôi tự hỏi nếu có bất kỳ khả năng tốt hơn, hoặc giải pháp phức tạp hơn?Làm cách nào để bố cục nhóm trong igraph?
Trả lời
Mở rộng trên gợi ý Gabor, tôi đã tạo ra chức năng này:
weight.community=function(row,membership,weigth.within,weight.between){
if(as.numeric(membership[which(names(membership)==row[1])])==as.numeric(membership[which(names(membership)==row[2])])){
weight=weigth.within
}else{
weight=weight.between
}
return(weight)
}
Đơn giản chỉ cần áp dụng nó trên các hàng của ma trận của các cạnh của đồ thị của bạn (do get.edgelist(your_graph))
để thiết lập các trọng cạnh mới (thành viên là vector thành viên từ kết quả của bất kỳ thuật toán phát hiện cộng đồng):
E(g)$weight=apply(get.edgelist(g),1,weight.community,membership,10,1)
Sau đó, chỉ cần sử dụng một thuật toán bố trí chấp nhận trọng lượng cạnh như fruchterman.reingold theo đề nghị của Gabor Bạn có thể tinh chỉnh các đối trọng để OB. tain đồ thị bạn muốn. Ví dụ:
E(g)$weight=apply(get.edgelist(g),1,weight.community,membership,10,1)
g$layout=layout.fruchterman.reingold(g,weights=E(g)$weight)
plot(g)
E(g)$weight=apply(get.edgelist(g),1,weight.community,membership,1000,1)
g$layout=layout.fruchterman.reingold(g,weights=E(g)$weight)
plot(g)
Lưu ý 1: tính minh bạch/màu sắc của các cạnh là các thông số khác của đồ thị của tôi. Tôi có các nút màu của cộng đồng để cho thấy rằng nó thực sự hoạt động.
Lưu ý 2: đảm bảo sử dụng membership(comm)
và không comm$membership
, trong đó comm
là kết quả của thuật toán phát hiện cộng đồng (ví dụ: comm=leading.eigenvector.community(g)
). Lý do là trong trường hợp đầu tiên, bạn nhận được một vector số với tên (những gì chúng ta muốn), và trong trường hợp thứ hai, cùng một vectơ không có tên.
Để nhận được sự đồng thuận của nhiều thuật toán phát hiện cộng đồng, hãy xem điều này function.
Chức năng layout.modular
cung cấp một bố trí nhóm cho một đồ thị, từ kết quả của bất kỳ igraph phương pháp phát hiện cộng đồng:
c <- fastgreedy.community(G)
layout.modular <- function(G,c){
nm <- length(levels(as.factor(c$membership)))
gr <- 2
while(gr^2<nm){
gr <- gr+1
}
i <- j <- 0
for(cc in levels(as.factor(c$membership))){
F <- delete.vertices(G,c$membership!=cc)
F$layout <- layout.kamada.kawai(F)
F$layout <- layout.norm(F$layout, i,i+0.5,j,j+0.5)
G$layout[c$membership==cc,] <- F$layout
if(i==gr){
i <- 0
if(j==gr){
j <- 0
}else{
j <- j+1
}
}else{
i <- i+1
}
}
return(G$layout)
}
G$layout <- layout.modular(G,c)
V(G)$color <- rainbow(length(levels(as.factor(c$membership))))[c$membership]
plot(G)
Một giải pháp sẽ được thiết lập trọng số cạnh của đồ thị, dựa trên các mô-đun hóa. Đặt các cạnh bên trong mô-đun cho một số trọng lượng lớn và giữa các cạnh mô-đun với một số trọng lượng nhỏ. Sau đó, gọi layout.fruchterman.reingold()
hoặc bất kỳ thuật toán nào hỗ trợ trọng số cạnh.
Bạn có thể cần phải chơi một chút với các giá trị trọng lượng thực tế, bởi vì điều đó phụ thuộc vào biểu đồ của bạn.
Hi Gabor, bạn có thể vui lòng xem [thread] liên quan này (http://stackoverflow.com/questions/31432176/potential-issue-with-new-igraph-layout-algorithms-r). Cảm ơn trước. – Antoine
Lấy cảm hứng về đề nghị Antoine, tôi tạo ra chức năng này:
edge.weights <- function(community, network, weight.within = 100, weight.between = 1) {
bridges <- crossing(communities = community, graph = network)
weights <- ifelse(test = bridges, yes = weight.between, no = weight.within)
return(weights)
}
Chức năng hoạt động tương tự; chỉ cần đặt đối tượng cộng đồng của bạn vào khe cộng đồng, biểu đồ của bạn trong mạng. Tôi đã để lại weight.between = 1
và điều chỉnh giá trị weight.within
.
Sau đó chuyển trọng lượng đến khe weight
trong các nút:
E(graph)$weight <- edge.weights(community, graph)
Cuối cùng sử dụng một thuật toán bố trí sử dụng trọng lượng như layout_with_fr
(tên gọi mới của fruchterman.reingold
trong igraph 1.0.1
).
Tôi sử dụng mạng lưới câu lạc bộ karate của Zachary làm ví dụ.
library(igraph)
library(igraphdata)
#I load the network
data(karate)
#for reproducible purposes
set.seed(23548723)
karateLayout <- layout_with_fr(karate)
par(mar = c(0,0,2,0))
plot(karate, vertex.size = 10, vertex.color = "steelblue4", edge.width = 1,
vertex.label = NA, edge.color = "darkgrey", layout = karateLayout,
main = "Zachary's karate club network")
tôi phát hiện cộng đồng bằng cách đa cấp tối ưu hóa các mô đun với cluster_louvain
chức năng:
Communitykarate <- cluster_louvain(karate)
Tiếp theo đó là một sở thích cá nhân so với giá trị mặc định:
prettyColors <- c("turquoise4", "azure4", "olivedrab","deeppink4")
communityColors <- prettyColors[membership(Communitykarate)]
Biểu đồ với cộng đồng được làm nổi bật bằng màu sắc là:
plot(x = Communitykarate, y = karate, edge.width = 1, vertex.size = 10,
vertex.label = NA, mark.groups = NULL, layout = karateLayout, col = communityColors,
main = "Communities in Zachary's karate club network",
edge.color = c("darkgrey","tomato2")crossing(Communitykarate, karate) + 1])
Bây giờ, ý nghĩa tại sao câu hỏi này tồn tại.
E(karate)$weight <- edge.weights(Communitykarate, karate)
# I use the original layout as a base for the new one
karateLayoutA <- layout_with_fr(karate, karateLayout)
# the graph with the nodes grouped
plot(x = Communitykarate, y = karate, edge.width = 1, vertex.size = 10,
mark.groups = NULL, layout = karateLayoutA, vertex.label = NA, col = communityColors,
c("darkgrey","tomato2")[crossing(Communitykarate, karate) + 1],
main = "Communities in Zachary's karate club network (grouped)")
Nếu bạn thử với trọng lượng hơn, bạn sẽ có có:
E(karate)$weight <- edge.weights(Communitykarate, karate, weight.within = 1000)
karateLayoutB <- layout_with_fr(karate, karateLayout)
plot(x = Communitykarate, y = karate, edge.width = 1, vertex.size = 10,
mark.groups = NULL, layout = karateLayoutB, vertex.label = NA, col = communityColors,
c("darkgrey","tomato2")[crossing(Communitykarate, karate) + 1],
main = "Communities in Zachary's karate club network (grouped)")
- 1. Làm cách nào để Trung tâm TextView trong Bố cục?
- 2. Bố cục nào tôi nên sử dụng để có được các cạnh không chồng chéo trong igraph?
- 3. Làm cách nào để tùy chỉnh bố cục WPF StatusBar?
- 4. thêm bố cục trong bố cục khác
- 5. Làm cách nào để tạo Nhóm trong GridView của Metro sử dụng các Bố cục khác nhau?
- 6. tọa độ nút cố định igraph bố trí
- 7. Sử dụng agility.js để bố cục trang và bố cục
- 8. Làm cách nào để tôi có thể thay đổi bố cục xml thành bố cục khác trên mã java?
- 9. Bố cục được bố trí khi nào?
- 10. Thêm bố cục vào bố cục khác trong Qt [C++]
- 11. Android sử dụng bố cục làm mẫu để tạo nhiều bản sao bố cục
- 12. Làm cách nào để tạo một ImageView trong mã java, trong một Bố cục hiện có?
- 13. Làm cách nào để căn giữa trong div phụ huynh trong bố cục lỏng
- 14. cách nghiêng bố cục trong Android?
- 15. Bố cục lưới Vs. Bố cục bảng
- 16. bố cục trong expressjs
- 17. Bố cục bố cục sai trong cửa sổ bật lên
- 18. Cách tốt nhất để chuyển đổi bố cục bảng thành bố cục CSS là gì?
- 19. Cách giữ bố cục gỡ lỗi giống như bố cục máy tính để bàn
- 20. cách mở tệp xml bố cục trong Trình chỉnh sửa bố cục Android?
- 21. Bố cục bố cục trong ứng dụng Android là gì?
- 22. Làm cách nào để căn giữa Chế độ xem bên trong Bố cục Android?
- 23. Làm cách nào để chuyển đổi tệp bố cục trong Zend Framework?
- 24. Làm cách nào để tạm ngưng và tiếp tục bố cục trong WPF?
- 25. Làm cách nào để tạo bố cục thích ứng trong WPF?
- 26. Làm cách nào để buộc vẽ lại/bố cục lại trong Ext GWT (GXT)?
- 27. Làm cách nào để tạo chân trang cố định trong bố cục android?
- 28. Làm cách nào để tăng bố cục chứa listview trong hộp thoại cảnh báo?
- 29. Làm cách nào để căn giữa nội dung bên trong bố cục tuyến tính?
- 30. Tôi làm cách nào để hiển thị danh sách Sencha Touch trong bố cục VBOX?
tôi nhận được một lỗi nếu tôi thử phương pháp của bạn. Tôi chỉ thêm hai dòng ở trên mã của bạn để mô phỏng một mạng, tức là: 'thư viện (igraph); G <- barabasi.game (100, được chỉ định = FALSE) '. Thông báo lỗi cho biết: 'Lỗi trong bố cục G $ [c $ membership == cc,] <- F $ layout: số lượng không chính xác các bảng con trên ma trận' – majom
Tôi cũng gặp lỗi tương tự. – imbenzene
Xin lỗi, điều này xảy ra vì 'G $ layout' là' NULL'. Nếu bạn điền vào nó với bất kỳ ma trận nào có kích thước chính xác, hoặc đơn giản với một 'G $ layout <- layout.fruchterman.reingold (G)', thì mã sẽ chạy tốt. – deeenes