thomasp85 / ggraph

Grammar of Graph Graphics
https://ggraph.data-imaginist.com
Other
1.08k stars 116 forks source link

Vertex attributes and labels missing when using sugiyama layout with dummy vertices #307

Closed aravind-j closed 10 months ago

aravind-j commented 2 years ago

Consider the following layered igraph network plotted with sugiyama layout. (As there are dummy vertices, the plotting of vertex labels is not straightforward.)

library(igraph)
nodes <- data.frame(key = c("B", "A", "C", "C1", "C2", "C3", "X", "P", "Y", "M", "N", "O", 
                            "G3", "G2", "G1", "G", "R", "S", "K1", "K2", "K3", "Z", "H", "I"),
                    inter = c(0, 0, 0, 1, 1, 1, 1, 4, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 
                              1, 1, 0, 0),
                    ret = c("F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "T", "F", 
                            "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F"))

edges <- data.frame(from = c("A", "C", "C1", "C2", "C3", "X", "M", "N", "O", "G3", "G2", 
                             "G1", "G", "R", "Z", "P", "K1", "K2", "O", "P", "B", "Y", "S", 
                             "X", "B"),
                    to = c("C", "C1", "C2", "C3", "X", "P", "Y", "M", "N", "O", "G3", 
                           "G2", "G1", "G", "R", "K1", "K2", "K3", "H", "I", "C", "P", "G", 
                           "H", "I"))

ig <- graph_from_data_frame(d = edges, directed = TRUE, vertices = nodes)

sug <-layout_with_sugiyama(ig)

origvert <- c(rep(TRUE, vcount(ig)),
              rep(FALSE, nrow(sug$layout.dummy)))
realedge <- as_edgelist(sug$extd_graph)[,2] <= vcount(ig)

plot(sug$extd_graph, vertex.label.cex=0.5,
     edge.arrow.size=0.05,
     edge.color = "black",
     vertex.size=ifelse(origvert, 10, 0),
     vertex.shape=ifelse(origvert, "square", "none"),
     vertex.label=ifelse(origvert, V(ig)$name, ""),
     edge.arrow.mode=ifelse(realedge, 2, 0),
     edge.curved = .1)

image

In ggraph while creating the same sugiyama layout, the vertex labels along with other vertex attributes are missing when dummy vertices are present.

library("ggraph")
sugig <- create_layout(ig, "sugiyama", use.dummy = TRUE)
head(sugig)
#>     x  y dummy circular .ggraph.index
#> 1 0.5 14 FALSE    FALSE             1
#> 2 1.5 14 FALSE    FALSE             2
#> 3 1.5 13 FALSE    FALSE             3
#> 4 1.5 12 FALSE    FALSE             4
#> 5 1.5 11 FALSE    FALSE             5
#> 6 1.5 10 FALSE    FALSE             6

ggraph(sugig) +
  geom_edge_elbow(strength = 0.75, color = "red", alpha = 0.8, end_cap = circle(4, 'mm'),
                  arrow = arrow(type = "closed", length = unit(2, 'mm'))) +
  geom_node_point(size = 1) +
  # geom_node_label(aes(label = name), size = 5) +
  theme(panel.background = element_blank())

image

However, the vertex labels and attributes are present when dummy vertices are ignored.

sugig <- create_layout(ig, "sugiyama")
head(sugig)
#>     x  y name inter ret .ggraph.orig_index circular .ggraph.index
#> 1 0.5 14    B     0   F                  1    FALSE             1
#> 2 1.5 14    A     0   F                  2    FALSE             2
#> 3 1.5 13    C     0   F                  3    FALSE             3
#> 4 1.5 12   C1     1   F                  4    FALSE             4
#> 5 1.5 11   C2     1   F                  5    FALSE             5
#> 6 1.5 10   C3     1   F                  6    FALSE             6

ggraph(sugig) +
  geom_edge_elbow(strength = 0.75, color = "red", alpha = 0.8, end_cap = circle(4, 'mm'),
                  arrow = arrow(type = "closed", length = unit(2, 'mm'))) +
  geom_node_point(size = 1) +
  geom_node_label(aes(label = name), size = 5) +
  theme(panel.background = element_blank())

image

schochastics commented 2 years ago

I would assume this is due to the way how the layout is returned from igraph. The names can be added easily though (and I think it is less tricky than with igraph)

library("ggraph")
library("igraph")

nodes <- data.frame(key = c("B", "A", "C", "C1", "C2", "C3", "X", "P", "Y", "M", "N", "O", 
                            "G3", "G2", "G1", "G", "R", "S", "K1", "K2", "K3", "Z", "H", "I"),
                    inter = c(0, 0, 0, 1, 1, 1, 1, 4, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 
                              1, 1, 0, 0),
                    ret = c("F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "T", "F", 
                            "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F"))

edges <- data.frame(from = c("A", "C", "C1", "C2", "C3", "X", "M", "N", "O", "G3", "G2", 
                             "G1", "G", "R", "Z", "P", "K1", "K2", "O", "P", "B", "Y", "S", 
                             "X", "B"),
                    to = c("C", "C1", "C2", "C3", "X", "P", "Y", "M", "N", "O", "G3", 
                           "G2", "G1", "G", "R", "K1", "K2", "K3", "H", "I", "C", "P", "G", 
                           "H", "I"))

ig <- graph_from_data_frame(d = edges, directed = TRUE, vertices = nodes)
sugig <- create_layout(ig, "sugiyama", use.dummy = TRUE)

sugig$name <- NA
sugig$name[1:vcount(ig)] <- V(ig)$name

head(sugig)
#>     x  y dummy circular .ggraph.index name
#> 1 0.5 14 FALSE    FALSE             1    B
#> 2 1.5 14 FALSE    FALSE             2    A
#> 3 1.5 13 FALSE    FALSE             3    C
#> 4 1.5 12 FALSE    FALSE             4   C1
#> 5 1.5 11 FALSE    FALSE             5   C2
#> 6 1.5 10 FALSE    FALSE             6   C3
ggraph(sugig) +
  geom_edge_elbow(strength = 0.75, color = "red", alpha = 0.8, end_cap = circle(4, 'mm'),
                  arrow = arrow(type = "closed", length = unit(2, 'mm'))) +
  geom_node_point(size = 1) +
  geom_node_label(aes(label = name), size = 5) +
  theme(panel.background = element_blank())

Created on 2022-05-03 by the reprex package (v2.0.1)