diagrammeR specifying node order and formatting text - r

I am using diagrammeR grViz to construct a flow chart. I would like to specify the order of some of the nodes that have the same rank. In the following chart, I would like to have Node 1 in the center rather than on the left. In addition, I would like to have "Node 2" underlined, but not "extra detail". Here is the code:
library("DiagrammeR")
grViz("
digraph CFA {
# Multiple level nodes
node [shape = rectangle, color=CornflowerBlue]
a [label = 'Node 1' ];
node [shape = ellipse, color=CornflowerBlue]
T1 [label = 'Node 2\\nextra detail'];
T2 [label = 'Node 3'];
{rank = same; a T1 T2}
# Connect nodes with edges and labels
a -> T1
a -> T2
}
")
Any help would be much appreciated. Also, if there are resources to help me along with these customization issues in diagrammeR, please include a link.

there are several ways to order the nodes. The easiest here is perhaps to have the edge T2 -> a in this order (rather than a -> T2), so node T2 is first and then use dir=back to reverse the arrow. You can use html to underline the node label. (also have to use break, <br/>, instead of newline,\n)
grViz("
digraph CFA {
a [label = 'Node 1', shape = rectangle, color=CornflowerBlue ];
node [shape = ellipse, color=CornflowerBlue]
T1 [label = <Node 2 <br/> <u>extra detail</u>>];
T2 [label = 'Node 3'];
{rank = same; a T1 T2}
# Connect nodes with edges and labels
a -> T1
T2 -> a[dir=back]
}
")
From comment: Is there a way to make a portion of the text in a node a different color (e.g. just the "extra detail", but not "Node 2")?
Yes, from the html link above you can "sets the color of the font within the scope of FONT.../FONT". So for example, change the label of T1 to
label = <Node 2 <br/> <font color='red'> <u>extra detail</u> </font> >

Related

Put an append list into a bar graph python

I know how to make a bar graph but I'm trying to put a append two append lists inside of the graph
one is the quantity of a item and the other is the item I would like to know if this is possible and if it is how should I do this. This is what I tried.
itemls = [0]
itemquantityls = [0]
option = 0
while option < 3:
Mainmenue = ["Main menue",
"1. ADD AN ITEM",
"2. GENERATE A CHART",
"3. EXIT"]
for i in (Mainmenue):
print(i)
option = int(input("Option you want:"))
if option == 1:
item = (input("add an item:"))
itemquantity = (input("Item quantity:"))
itemls.append(item)
itemquantityls.append(itemquantity)
elif option == 2:
import matplotlib.pyplot as plt
plt.bar(itemls, itemquantityls)
plt.title('Items and quantity')
plt.xlabel('Item')
plt.ylabel('Item quantity')
plt.show()
elif option == 3:
print("program is teminating")
else:
print("Wrong Input try again")
Thanks in advance. :)

R diagrammeR using html for formatting while reading text from r variable

I'm creating a flow chart with the R package diagrammer. To get desired formatting (bold, bullet, left-justify) I can write node label in html. However, I also want to populate some of the text by calling variables in R, and I can't figure out how to do both (html formatting + call R variables) at the same time.
In this code snippet, the html formatting works but instead of printing the string assigned to the variable 'text_var', it prints the string 'text_var'.
library(DiagrammeR)
text_var = 'Some text'
grViz("digraph flowchart {
# Node definitions
node [fontname = Helvetica, shape = box]
tab1 [label = <<b> Node 1 </b> <br ALIGN = 'LEFT' /> • text_var <br ALIGN = 'LEFT' />
>]
tab2 [label = 'Node 2']
# Edge definitions
tab1 -> tab2
}")
In this code snippet, I am print the string assigned to the variable 'text_var', but there's no html.
library(DiagrammeR)
text_var = 'Some text'
grViz("digraph flowchart {
# Node definitions
node [fontname = Helvetica, shape = box]
tab1 [label = '##1']
tab2 [label = 'Node 2']
# Edge definitions
tab1 -> tab2
}
[1]: paste0('Node 1 \\n ', text_var)
")
Desired result is the text from the second example with the formatting from the first. Thank you!
Although the solution by Allan Cameron works, it is also possible to use
Graphviz Substitution.
I found the implementation rather buggy however, although ##1 should work in the below example, I found that it took over 3 minutes of full CPU usage before I shut it off. ##1-1 seems to work.
text_var = 'Some text'
grViz("
digraph flowchart {
# Node definitions
node [fontname = Helvetica, shape = box]
tab1 [label = <
<b>Node 1</b>
<br ALIGN = 'LEFT' />
• ##1-1
<br ALIGN = 'LEFT' />
>]
tab2 [label = 'Node 2']
# Edge definitions
tab1 -> tab2
}
[1]: text_var"
)
R doesn't know that you want the string "text_var" inside the string you are passing to grViz to be replaced by the actual variable text_var containing your string. Try this instead:
grViz(gsub("text_var", text_var, "digraph flowchart {
# Node definitions
node [fontname = Helvetica, shape = box]
tab1 [label = <<b> Node 1 </b> <br ALIGN = 'LEFT' /> • text_var <br ALIGN = 'LEFT' />
>]
tab2 [label = 'Node 2']
# Edge definitions
tab1 -> tab2
}"))
```

Subgraph doesn't appear in graphviz chart

I can't figure out, why subgraph doesn't work here:
digraph virtPfr {
node [
shape=box
]
Start [
style=rounded,
label="create folder profiles"
]
subgraph asd {
label = "copy files from other profiles"
cpIfDestFilesExist [
label = "Check for file existance"
]
Cp [
label = "Copy"
]
}
Start -> asd
cpIfDestFilesExist -> Start
cpIfDestFilesExist -> Cp
}
but this code works:
digraph G {
node [
shape = "record"
]
Animal [
label = "Animal name and age"
]
subgraph clusterAnimalImpl {
label = "Package animal.tmpl"
Dog [
label = "Dog name and age"
]
Cat [
label = "Cat name and age"
]
}
Dog -> Animal
Cat -> Animal
Dog -> Cat
}
I don't understand, what's different on the top graph, in comparison to the bottom graph, that the bottom works, but the top doesn't. I've already pulled my eyes out. I don't see the problem here.
Please, help
A couple of issues:
Sub-graph names have to start with the keyword cluster.
You can't connect edges directly to a sub-graph, instead you can use the lhead/ltail workaround described here.
For your graph, it could like as follows:
digraph virtPfr {
graph [compound=true]
node [
shape=box
]
Start [
style=rounded,
label="create folder profiles"
]
subgraph cluster_asd {
label = "copy files from other profiles"
cpIfDestFilesExist [
label = "Check for file existance"
]
Cp [
label = "Copy"
]
}
Start -> cpIfDestFilesExist [lhead=cluster_asd]
cpIfDestFilesExist -> Start
cpIfDestFilesExist -> Cp
}
Which generates the following output:

grViz diagrammeR: justifying rows of nodes

I am using diagrammeR with grViz to generate a flow chart with multiple rows. The rows are grouped together properly, and the vertical order works well. Is there a way to specify justification of full rows (ranks)? I would like them to be centered. Below is code and an image of the example I am working with. I would like rows 3 and 4 to be centered.
Any input would be greatly appreciated.
Thanks.
library("DiagrammeR")
grViz("
digraph CFA {
# Multiple level nodes
node [shape = rectangle, color=CornflowerBlue]
a [label = <<FONT COLOR='blue' POINT-SIZE='18'><b>Surveillance 2017 </b> <br/>Urban Mixtures</FONT>> ];
# http://www.graphviz.org/doc/info/shapes.html#html
#Tiers
node [shape = ellipse, color=CornflowerBlue]
T1 [label = <<u><b><font color = 'forestgreen' point-size = '16'>Tier 1</font></b></u><br/>Water Quality <br/> 16 Watersheds <br/> Quarterly sampling>];
T2 [label = <<u><b><font color = 'forestgreen' point-size = '16'>Tier 2</font></b></u> <br/> Sediment and Passive sampling <br/> 72 Sites>];
#Media assays and ancillary
chem [label = 'Water \\nChemistry'];
bio [label = 'Bio-effects'];
Anc [label = 'Ancillary \\ndata']
sed [label = 'Sediment \\nChemistry'];
pass [label = 'Passive Sampler \\nChemistry'];
# Analyses
node [shape = box, color = Crimson]
owc [label = 'Waste Indicators'];
PFAS [label = 'PFAS: 30 sites']
PAH [label = 'PAHs'];
Att [label = 'Attagene'];
Met [label = 'Metabolomics'];
Tr [label = 'Transcriptomics'];
Hyd [label = 'Hydrology'];
WA [label = 'Watershed \\nAttributes']
# Synthesis
node [shape = 'egg',color = ' forestgreen']
Syn [label = 'Synthesis'];
Tx [label = 'ToxEval\\nHTS/AOP analysis']
{rank = same; T1 T2}
{rank = same; chem bio pass sed Anc}
# {rank = same; PFAS; PAH; WA; Hyd; owc;Att;Met;Tr}
{rank = same; PFAS; PAH; Hyd; owc;WA; Hyd}
{rank = same; Att;Met;Tr}
{rank = same; Tx; Syn}
# Connect nodes with edges and labels
T1 -> a[dir=back]
a -> T2#[dir=back]
T1 -> {bio chem Anc}
T2 -> {bio sed Anc pass chem}
Anc -> {Hyd WA}
chem -> {owc}
chem -> PFAS [label = 'Tier 2']
sed -> {owc PAH}
pass -> PAH
bio -> {Met Tr} [label = 'Tier 1']
bio -> {Att} [label = 'Tier 2']
{owc Att Met Tr Hyd WA PAH PFAS} -> Syn
{owc PAH PFAS} -> Tx
Tx -> Syn
}
")
example flow chart

Positionating and arrow direction in GraphViz

I'm trying to migrate some realy old documentation to our internal wiki using GraphViz.
I'm not used to the Dot language, and needs some help
See following example:
I have experiment a lot, but the best I have come up to so far is this:
digraph CentralPmr {
fontname="Helvetica";
shape=box;
node[shape=box];
graph [splines=ortho]
sg [label="TTD storage group for\nthe logged values"]
vc [label="Value catalogue"]
tc1 [label="Time catalogoue (1)"]
tc2 [label="Time catalogoue (2)"]
sv_ [shape=point,width=0.01,height=0.01];
sv [label=""]
ie [shape=none, label="Initiating event"]
c1 [shape=none, label="The set of values, defined\nby the value catalogue, which\nare freezed out of the TTD\nstorage group of the actual log."]
c2 [shape=none, label="Time catalogue defining\nat what time around the\ninitiating event values\nshould be collected."]
sgf [shape=record, label="{<f0> 1|2|3|4|..}|{ | | | | }"]
sg -> sv_ [penwidth=4, dir=none];
sv_ -> sv -> tc2 [penwidth=4]
sv -> sgf:f0 [penwidth=4]
{vc, tc1} -> sg
c1 -> sv [style=dashed, arrowhead="open"];
{rank=min; ie}
{rank=same; sg c1}
{rank=same; vc sgf}
{rank=max; rc2}
}
It don't have to be exactly the same as the source, but I want it to be understandable.
The problems is:
How do I place the text between "Value catalogue" and "Time catalogue (1)"?
[Edit] How do I force the arrow to "TTD storage group for PMR-freezed value" to go from the side, and not from the above? It is a virtualization of a memory area, and the arrow are pointing to a specific memory post. In other images, it can point to a other memory post in the memory area (eg. 2 , 3, 4..).
Is it possible to create a zigzag line from the "Initiating event"?
How do I place the legends in the bottom that explains the different types of lines?
[edit] How do I add the comments above, under and to the right of the "TTD storage group for PMR-freezed values"?
[Edit] How do I make the "TTD storage group for PMR-freezed value" wider?
This is on top of my first answer in a way that editing that one would create too much confusion. I have tried to take all your needs into consideration and it only works (I believe) if you give up the splines=ortho requirement. Pls refer to the comments below my first answer. Here we go:
digraph CentralPmr {
fontname="Helvetica";
shape=box;
node[shape=box];
// graph [splines=ortho]
sg [label="TTD storage group for\nthe logged values", width = 2.5]
sv[ label="", width = 2]
ie [ shape=none, label="Initiating event", fontsize = 18 ]
c1 [ shape=none, label="The set of values, defined\nby the value catalogue, which\nare freezed out of the TTD\nstorage group of the actual log." ]
sgf[shape=box, margin=0, label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
<TR>
<TD BORDER="0" COLSPAN="2">TTD storage group for<BR/>PMR freezed values</TD>
</TR>
<TR>
<TD PORT="f1">1</TD>
<TD BORDER="0" ROWSPAN="6">The set of<BR/>values is<BR/>stored in<BR/>the TTD<BR/>storage<BR/>group</TD>
</TR>
<TR>
<TD>2</TD>
</TR>
<TR>
<TD>3</TD>
</TR>
<TR>
<TD>4</TD>
</TR>
<TR>
<TD>-</TD>
</TR>
<TR>
<TD>-</TD>
</TR>
<TR>
<TD BORDER="0" COLSPAN="2">Up to nine freezing areas<BR/>for defined central PMR</TD>
</TR>
</TABLE>>];
TTD [shape=none, margin=0, label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="12">
<TR>
<TD PORT="f1">Value catalogue</TD>
</TR>
<TR>
<TD BORDER="0"></TD>
</TR>
<TR>
<TD PORT="f2">Time catalogue (1)</TD>
</TR>
<TR>
<TD BORDER="0">Time catalogue defining<BR/>at what time around the<BR/>initiating event values<BR/>should be collected</TD>
</TR>
<TR>
<TD PORT="f3">Time catalogue (2)</TD>
</TR>
</TABLE>>];
connector_1[ shape = point height = 0 width = 0 margin = 0 ]
ie -> connector_1[ style = dotted, arrowhead = none ];
{ rank = same; connector_1 c1 }
connector_1 -> c1[ style = invis, minlen = 4 ];
c1 -> sv[ style = dashed, arrowhead = open ];
connector_2[ shape = point height = 0 width = 0 margin = 0 ]
connector_1 -> connector_2[ style = dotted ];
{ rank = same; sg connector_2 sv }
sg -> connector_2[ minlen = 3, penwidth = 4, arrowhead = none ];
connector_2 -> sv[ minlen = 3, penwidth = 4 ];
sg:sw -> TTD:f1:nw[ weight = 5 ];
sg:w -> TTD:f2:w;
sv:sw -> TTD:f3:e[ penwidth = 4 ];
sv:sw -> sgf:f1:w[ penwidth = 4 ];
node[ shape = plaintext ];
leg2[ label = "Data flow" ];
leg4[ label = "Reference" ];
leg6[ label = "Comment" ];
node [ shape = point height = 0 width = 0 margin = 0 ];
leg1 leg3 leg5
TTD:sw -> leg1[ style = invis ];
{ rank = same; leg1 leg2 leg3 leg4 leg5 leg6 }
edge[ minlen = 2 ];
leg1 -> leg2[ penwidth = 4 ];
leg3 -> leg4[ style = dotted ];
leg5 -> leg6[ style = dashed, arrowhead = open ];
}
yields
Not sure whether I understand completely what you want but below my take on it. This is just a first attempt, much more fine-tunig can be done. I would probably use HTML-like nodes where text and "box" need to be closer, in particular for that "TTD Storage Group for PMR freezed values" in the original graph.
My answers to your questions would be:
How do I place the text between "Value catalogue" and "Time catalogue (1)"?
--- See below. I have put it between the two time catalogues as in the original graph but easy to move around.
How do I force the arrow to the record go from the side, and not from the above?
--- See below. You could also use rankdir = LR; to change the orientation if that is your question.
Is it possible to create a zigzag line from the "Initiating event"?
--- There are ways, but a lot of effort (like creating a custom shape). Nothing "out of the box", to the best of my knowledge.
How do I place the legends in the bottom?
I don't really understand, but in general, the answer would be HTML-like labels when we talk about nodes.
Her is what I have done:
digraph CentralPmr
{
fontname="Helvetica";
shape=box;
node[shape=box];
graph [splines=ortho]
sg [label="TTD storage group for\nthe logged values"]
vc [label="Value catalogue"]
tc1 [label="Time catalogoue (1)"]
tc2 [label="Time catalogoue (2)"]
sv_ [shape=point,width=0.01,height=0.01];
sv [label="", width = 2]
ie [shape=none, label="Initiating event"]
c1 [shape=none, label="The set of values, defined\nby the value catalogue, which\nare freezed out of the TTD\nstorage group of the actual log."]
c2 [shape=none, label="Time catalogue defining\nat what time around the\ninitiating event values\nshould be collected."]
sgf [shape=record, label="{<f0> 1|2|3|4|..}|{ | | | | }"]
connector_1[ shape = point height = 0 width = 0 margin = 0 ]
ie -> connector_1[ style = dotted, arrowhead = none ];
{ rank = same; connector_1 c1 }
connector_1 -> c1[ style = invis ];
c1 -> sv[ style = dashed, arrowhead = open ];
connector_2[ shape = point height = 0 width = 0 margin = 0 ]
connector_1 -> connector_2[ style = dotted ];
{ rank = same; sg connector_2 sv }
sg -> connector_2[ minlen = 3, penwidth = 4, arrowhead = none ];
connector_2 -> sv[ minlen = 3, penwidth = 4 ];
vc -> tc1 -> c2 -> tc2[ style = invis, weight = 10 ];
sg -> vc;
sg -> tc1;
sv -> tc2[ penwidth = 4 ];
sv -> sgf;
}
yields

Resources