0

I need to plot directed network with 2-way edges and labels on nodes. Node names lengths are sometimes short, sometimes long. Data is dynamically generated so it's a kind of random every time.

Here is my example with data:

library(DiagrammeR)

# create data:
links=data.frame(
    source=c("AAAAAAAAAAAAAAAAAAAAAAAA","AAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAA","J", "BBBBBBBBB",
             "BBBBBBBBBBBBBBBBBBBBB", "CCCCCCCCCCC", "CCCCCCCCCCC", "D","IIIIIIII"),
    target=c("BBBBBBBBBBBBBBBBBBBBB","BBBBBBBBBBBBBBBBBBBBB", "CCCCCCCCCCC", "D", 
             "J","AAAAAAAAAAAAAAAAAAAAAAAA","E", "F", "G", "H", "IIIIIIII","IIIIIIII")
)


labels <- unique(c(links$source,links$target))

nodes <- data.frame (id = labels, label = labels )

i_graph_1 <-
    DiagrammeR::create_graph() %>% 
    DiagrammeR::add_nodes_from_table(
        table = nodes,
        label_col = label) %>% 
    DiagrammeR::add_edges_from_table(
        table = links,
        from_col = source,
        to_col = target,
        from_to_map = id_external)%>% 
    select_nodes_by_id(nodes = 1:length(labels)) %>% 
    set_node_attrs_ws(
        node_attr = shape,
        value = "rectangle") %>% 
    clear_selection()

gr <- i_graph_1 %>% DiagrammeR::render_graph()

writeLines(
    export_svg(gr), "c:\\temp\\n1.svg"
    )



My result picture:

enter image description here

  1. Is it possible to make A<->B, A<->J links bidirectional instead of 2 one-way links?
  2. Is it possible to fit labels in nodes and not overlap nodes borders?

UPDATE:

If I use fixedsize = False, result is still not good. Nodes overlap.

i_graph_1 <-
    DiagrammeR::create_graph() %>% 
    DiagrammeR::add_nodes_from_table(
        table = nodes,
        label_col = label) %>% 
    DiagrammeR::add_edges_from_table(
        table = links,
        from_col = source,
        to_col = target,
        from_to_map = id_external)%>% 
    select_nodes_by_id(nodes = 1:length(labels)) %>% 
    set_node_attrs(node_attr = "fixedsize",values = FALSE) %>% 
    set_node_attrs_ws(
        node_attr = shape,
        value = "rectangle") %>% 
    clear_selection()

enter image description here

Maxim
  • 301
  • 1
  • 9
  • How is this different to your [previous question](https://stackoverflow.com/questions/70516716/fix-nodes-overlap-in-igraph)? – Limey Dec 30 '21 at 11:03
  • That one was about igraph, this one about DiagrammeR. Different code, data structures and renderers. – Maxim Dec 30 '21 at 11:05
  • In that case, you appear to be agnostic to the implementation of the solution. It might be better to create a single generic question than two implementation-specific ones. That will avoid the possibility of people wasting time on a second, rediundant, solution. – Limey Dec 30 '21 at 11:27
  • I can do this but this question will contain hundreds of lines of codes and 3 big pictures. I asked same question about Cytoscape also. Not sure it's good approach. – Maxim Dec 30 '21 at 11:29
  • `set_node_attrs(node_attr = "fixedsize",values = FALSE)` ; see https://rich-iannone.github.io/DiagrammeR/ndfs_edfs.html for attributes that can be changed . – user20650 Dec 30 '21 at 13:11

2 Answers2

1

The key was to use graphviz attributes layout = dot, concentrate = true.

And node_attr = "fixedsize",values = FALSE.

library(DiagrammeR)

# create data:
links=data.frame(
    source=c("AAAAAAAAAAAAAAAAAAAAAAAA","AAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAA","J", "BBBBBBBBB",
             "BBBBBBBBBBBBBBBBBBBBB", "CCCCCCCCCCC", "CCCCCCCCCCC", "D","IIIIIIII"),
    target=c("BBBBBBBBBBBBBBBBBBBBB","BBBBBBBBBBBBBBBBBBBBB", "CCCCCCCCCCC", "D", 
             "J","AAAAAAAAAAAAAAAAAAAAAAAA","E", "F", "G", "H", "IIIIIIII","IIIIIIII")
)

# Turn it into igraph object


labels <- unique(c(links$source,links$target))

nodes <- data.frame (id = labels, label = labels )

i_graph_1 <-
    DiagrammeR::create_graph() %>% 
    add_global_graph_attrs("layout", "dot", "graph") %>%
    add_global_graph_attrs("concentrate", "true", "graph") %>%
    DiagrammeR::add_nodes_from_table(
        table = nodes,
        label_col = label) %>% 
    DiagrammeR::add_edges_from_table(
        table = links,
        from_col = source,
        to_col = target,
        from_to_map = id_external)%>% 
    select_nodes_by_id(nodes = 1:length(labels)) %>% 
    set_node_attrs(node_attr = "fixedsize",values = FALSE) %>% 
    set_node_attrs_ws(
        node_attr = shape,
        value = "rectangle") %>% 
    clear_selection()


gr <- i_graph_1 %>% DiagrammeR::render_graph( )
gr

Here is the result:

enter image description here

Maxim
  • 301
  • 1
  • 9
0

Not sure about 1. But 2 is possible. You just need to use the edge_aes(dir="both") property. https://rdrr.io/cran/DiagrammeR/man/edge_aes.html

library(DiagrammeR)
library(dplyr)

graph <-
  create_graph() %>%
  add_path(
    n = 3,
    type = "path",
    edge_aes = edge_aes(
      style = "dot",
      color = c("red", "blue"),
      dir="both"))


graph %>%
  get_edge_df()

my_graph <- graph %>% DiagrammeR::render_graph()
my_graph
thehand0
  • 1,123
  • 4
  • 14