How to use GraphViz graphs in DiagrammeR for R - r

I am trying to use a GraphViz graph in DiagrammeR. How can I do this?
myGraph = 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
}
")
and then I want to use it in DiagrammeR, but it will not allow it.
render_graph(myGraph)
Gives:
Error: class(graph) == "dgr_graph" are not all TRUE
Is there a way I need to convert or input the GraphViz graph into the DiagrammeR environment?

grViz takes a string describing the graph (vis.js style) : it is the interpreted by vis.js. Its return value is then an htmlwidget object.
render_graph takes a dgr_graph object, created using the create_graph function.
you can see in the DiagrammeR doc
library(DiagrammeR)
# Create a simple NDF
nodes <-
create_nodes(
nodes = 1:4,
type = "number")
# Create a simple EDF
edges <-
create_edges(
from = c(1, 1, 3, 1),
to = c(2, 3, 4, 4),
rel = "related")
# Create the graph object,
# incorporating the NDF and
# the EDF, and, providing
# some global attributes
graph <-
create_graph(
nodes_df = nodes,
edges_df = edges,
graph_attrs = "layout = neato",
node_attrs = "fontname = Helvetica",
edge_attrs = "color = gray20")
# View the graph
render_graph(graph)
DiagrammeR can produce Graphviz code : From the doc mentioned below : "If you'd like to return the Graphviz DOT code (to, perhaps, share it or use it directly with the Graphviz command-line utility), just use output = "DOT" in the render_graph()"
So
you can use create_graph to produce graphviz dot code
you can use graphviz dot code directly with grViz in DiagrammeR

Here the problem is with render_graph(myGraph), using just myGraph works like charm.
library(DiagrammeR)
myGraph = 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
}
")
myGraph
render_graph(myGraph) Does not work in R.
Just myGraph works fine.

Related

flowchart using digraph in Diagrammer

I'm trying out DiagrammeR to build some flowcharts and I'm interested in knowing whether I can include values from a secondary data frame (data pulled from a SQL database).
I'm using an example from the documentation and I want to add a random value from the Iris dataset.
I wish to add iris[2,4] as a subtext to the ELEPHANT node in my code below, is this possible?
library(DiagrammeR)
grViz("
digraph {
# graph attributes
graph [overlap = true]
# node attributes
node [shape = box,
fontname = Helvetica,
color = blue]
# edge attributes
edge [color = gray]
# node statements
A; B; C; D; ELEPHANT
F [color = black]
# node attributes
node [shape = circle,
fixedsize = true,
width = 0.9]
# node statements
1; 2; 3; 4; 5; 6; 7; 8
# edge statements
A->1; B->2 // gray
B->3 [color = red] // red
B->4 // gray
C->A [color = green] // green
1->D; ELEPHANT->A; 2->4; 1->5; 1->F // gray
ELEPHANT->6; 4->6; 5->7; 6->7 // gray
3->8 [color = blue] // blue
}
")
I believe what I'm looking for is a parameterized diagram which is detailed here https://mikeyharper.uk/flowcharts-in-r-using-diagrammer/
You can achieve this by adding 2 simple steps, please see the example code and comments below:
library(DiagrammeR)
grViz("
digraph {
# graph attributes
graph [overlap = true]
# node attributes
node [shape = box,
fontname = Helvetica,
color = blue]
# edge attributes
edge [color = gray]
# node statements
A; B; C; D; ELEPHANT[label = '##1'] # Here calls label from 1 below
F [color = black]
# node attributes
node [shape = circle,
fixedsize = true,
width = 0.9]
# node statements
1; 2; 3; 4; 5; 6; 7; 8
# edge statements
A->1; B->2 // gray
B->3 [color = red] // red
B->4 // gray
C->A [color = green] // green
1->D; ELEPHANT->A; 2->4; 1->5; 1->F // gray
ELEPHANT->6; 4->6; 5->7; 6->7 // gray
3->8 [color = blue] // blue
}
[1]: paste0('iris[2, 4] is ', iris[2, 4]) # here is the label and value
")
You should be able to see the same result like this

DiagrammeR general flow direction

I would like to produce a diagram with DiagramR.
This is my code
require(DiagrammeR)
grViz("
digraph boxes_and_circles {
node [shape = box,
fontname = Helvetica]
A; B; C; D
B->A C->A D->B
}
")
But I get this result
And I need like this one
How can I set flow direction to up?
You could to set the parameter rankdir and add the color to edge and node:
library(DiagrammeR)
grViz("
digraph boxes_and_circles {
rankdir = BT
node [shape = box,
fontname = Helvetica,
color = gray
]
A; B; C; D
edge [color = gray]
B->A C->A D->B
}
")

graphviz dot ignores 'rank' constraints

I constructed a simple graph:
digraph{
rankdir = LR;
{
rank="source";
Sa;
Sb;
Sc;
St;
}
St -> {t_1[label="t",shape=plaintext];}
Na;
{t_a[label="t",shape=plaintext];}->Na
Sa->Na;
Sb->Na;
Sc->Na;
subgraph cluster_b {
fillcolor = "#ddDDdd";
style=filled;
label="";
Nb1;
Nb;
Nb1->Nb;
}
{t_2[label="t",shape=plaintext];}->Nb1
Sa->Nb;
Nc;
{t_c[label="t",shape=plaintext];}->Nc
Nd;
{t_d[label="t",shape=plaintext];}->Nd
Na->Nd;
Nb->Nc;
Nd->O1;
Nc->Nd;
{
rank="sink";
O1;
}
}
view online here
It seems that dot is ignoring the rank="source".
According to the documentation
If rank="min", all nodes are placed on the minimum rank. If
rank="source", all nodes are placed on the minimum rank, and the only
nodes on the minimum rank belong to some subgraph whose rank attribute
is "source" or "min".
The Sx nodes should be the only ones on the lowest ranks.
(as if there would be an additional St->t_2[style=invis]; edge).
Is this a bug? do i misunderstand the documentation?
I vote "bug" (probably in software, maybe in documentation).
Here is a work-around, using the minlen attribute to "force" the Nb node (and the cluster) "down" the ranks.
digraph{
rankdir = LR;
{
rank="source";
Sa;
Sb;
Sc;
St;
}
St -> {t_1[label="t",shape=plaintext];}
Na;
{t_a[label="t",shape=plaintext];}->Na
Sa->Na;
Sb->Na;
Sc->Na;
subgraph cluster_b {
fillcolor = "#ddDDdd";
style=filled;
label="";
Nb1;
Nb;
Nb1->Nb;
}
{t_2[label="t",shape=plaintext];}->Nb1
Sa->Nb [minlen=3] // will this move the cluster??
Nc;
{t_c[label="t",shape=plaintext];}->Nc
Nd;
{t_d[label="t",shape=plaintext];}->Nd
Na->Nd;
Nb->Nc;
Nd->O1;
Nc->Nd;
{
rank="sink";
O1;
}
}
Giving:

add text to DiagrammeR flowchart flowline in R

The following code creates a flowchart in R with the DiagrammeR package. How can I add "Yes" or "No" (or any other text) to the flowlines connecting the shapes? When creating charts, my nodes will often be decisions, and I'd like to label the flowline answer as Yes/No.
library(DiagrammeR)
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
}
")
Try to define the label for each flowline, like this:
library(DiagrammeR)
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 [label='YES']
B->2 [label='NO']
B->3 [label='...']
B->4 C->A
1->D E->A 2->4 1->5 1->F
E->6 4->6 5->7 6->7 3->8
}
")
Hope it helps! :)

Algorithm to generate interval graph

I wonder if there is any algorithm or some easy procedure to generate an interval graph?
I need to generate interval graphs with n nodes, where n is changing for 1 to, say, 10000.
If it is possible, I need an incidence matrix representation of the graph.
An additional restriction is not to have all these graphs complete.
Thanks everyone in advance!
==ADDITION==
Here is an implementation in Java:
public Object generate(int numberOfNodes) {
int listCapacity = numberOfNodes * 2;
List<Integer> arr = new ArrayList<Integer>();
int[][] adjacencyMatrix = new int[numberOfNodes][numberOfNodes];
Integer nodeNumber = 0;
for (int i = 0; i < listCapacity; i = i + 2) {
arr.add(nodeNumber);
arr.add(nodeNumber);
nodeNumber++;
}
Collections.shuffle(arr);
for (int i = 0; i < numberOfNodes; i++) {
for (int j = arr.indexOf(i); j < arr.lastIndexOf(i); j++) {
adjacencyMatrix[i][arr.get(j)] = 1;
adjacencyMatrix[arr.get(j)][i] = 1;
}
adjacencyMatrix[i][i] = 0;
}
return new Graph(adjacencyMatrix);
}
Though, in some cases it fails to produce interval graph.
One possible way to generate an interval graph with N nodes:
create an array [1, 1, 2, 2, ... n, n]
shuffle the array
create a graph:
each node v_i corresponds to the pair of occurences of i in the shuffled array
two nodes v_i and v_j are connected with an edge iff i and j are interleaved in the array. That is i j i j or i j j i, but not i i j j. In other words, the intervals i and j intersect.
This graph is guaranteed to be an interval graph (every node is an interval in the original array), and every graph is possible to create this way.

Resources