Search code examples
rdiagramhtmlwidgets

Combine different grViz into a single plot


I would like to combine different DiagrammeR plots into a single figure. The plots are generated as the following example:

library(DiagrammeR)
pDia <- grViz("
digraph boxes_and_circles {

  # a 'graph' statement
  graph [overlap = true, fontsize = 10]

  # several 'node' statements
  node [shape = box,
        fontname = Helvetica]
  A; B; C; D; E; F

  node [shape = circle,
        fixedsize = true,
        width = 0.9] // sets as circles
  1; 2; 3; 4; 5; 6; 7; 8

  # several 'edge' statements
  A->1 B->2 B->3 B->4 C->A
  1->D E->A 2->4 1->5 1->F
  E->6 4->6 5->7 6->7 3->8
}
")

pDia

enter image description here

Therefore, I would like to combine plots like pDia, class "grViz" "htmlwidget", into a single image with labels such A, B and so on. I tried to export a svg file of the plot with the exportSVG function. Thus, would be possible to use the magick package to import and deal with different plots of such a class (i.e. "grViz" "htmlwidget"). However, this function is not available in the newer version of the DiagrammeR package. Any ideas to combine these plots in a figure that could be exported to a figure file such as pdf or tiff?


Solution

  • Perhaps one of the following approaches will suit your needs.

    1. You can add additional/disconnected graphs by just adding them to the same digraph call. For example, we can add two other graphs (U -> V -> W and X -> Y -> Z) to the right of your graph by just adding the nodes & edges after the other graph; you just need to make sure the nodes are named differently from the nodes in the preceding graphs. This can however, lead to large complicated scripts and may not suit your workflow.
    library(DiagrammeR)
    pDia <- grViz("
    digraph boxes_and_circles {
    
      # your existing graph here
    
      # 2nd graph
      U -> V -> W;
      
      # 3rd graph
      X -> Y -> Z;
    }")
    

    enter image description here

    1. Given that you are wanting a static output it is probably easier just to go straight to graphviz. One way to combine graphs is by adding them as images to existing nodes. For example, if you have two graphs saved as png (other formats):
    cat(file="so-65040221.dot", 
    " 
    digraph boxes_and_circles {
      graph [overlap = true, fontsize = 10]
      node [shape = box, fontname = Helvetica]
      A; B; C; D; E; F
      node [shape = circle, fixedsize = true, width = 0.9] 
      1; 2; 3; 4; 5; 6; 7; 8
      A->1 B->2 B->3 B->4 C->A
      1->D E->A 2->4 1->5 1->F
      E->6 4->6 5->7 6->7 3->8
    }")
    
    # This will write out two pngs. We will use these as examples for us to combine
    system("dot -Tpng -Gdpi=300 so-65040221.dot -o so-65040221A.png -o so-65040221B.png")
    

    Then create a new graph to read in the pngs and add them to the nodes

    cat(file="so-65040221-combine.dot", 
    'graph {
            node [shape=none]
            a [label="", image="so-65040221A.png"];
            b [label="", image="so-65040221B.png"];
    }')
    

    We execute this and output to pdf with

    system("dot -Tpdf so-65040221-combine.dot > so-65040221-combine.pdf")
    # or output tiff etc
    # system("dot -Ttif so-65040221-combine.dot > so-65040221-combine.tiff")
    

    enter image description here

    You can then arrange multiple graphs by how you arrange the nodes in the combined script.