I am trying to make plot of several disconnected graphs.
digraph {
// rankdir=RL
subgraph template {
node [shape=square]
edge [color=black]
subgraph top {
node [group=1]
A
B
C
D
E
}
subgraph bottom {
node [group=2]
F
G
H
}
}
C -> c
F -> f
subgraph s1 {
edge [color=red]
A -> a
B -> b1
D -> d1
E -> e1
G -> g1
H -> h1
}
subgraph s2 {
edge [color=blue]
A -> b1
B -> a
D -> d2
E -> e2
G -> g2
H -> h2
}
subgraph s3 {
edge [color=green]
A -> a
B -> b1
D -> d2
E -> e3
G -> g3
H -> h1
}
subgraph s4 {
edge [color=purple]
A -> b1
B -> a
D -> e1
E -> e2
G -> g4
H -> h1
}
subgraph s5 {
edge [ color=orange]
A -> b1
B -> a
D -> d5
E -> e1
G -> g5
H -> h1
}
subgraph s6 {
edge [ color=brown]
A -> a
B -> b1
D -> d1
E -> e6
G -> g6
H -> h1
}
subgraph s6 {
edge [ color=tan]
A -> a
B -> b2
D -> d2
E -> e6
G -> g6
H -> h1
}
}
This creates a short, wide graph.
I would like to have a taller, narrower graph. For example, moving the F, G and H trees under the A-E nodes would be good.
I tried size, which just made the nodes bigger or smaller.
I tried ratio, which stretched the graph but did not move nodes around.
I tried using group and/or rankdir, but neither did what I wanted.
I have mostly tried using fdp, but also tried dot.
I am happy with a solution that either automatically moves the nodes around or requires me to manually move them.
Any suggestions on how to achieve this?
Here are two ways:
(easiest)
make each top-level cluster a stand-alone graph.
run each graph through dot -Tdot myfileX.gv >myfileX.dot
use gvpack (https://graphviz.org/pdf/gvpack.1.pdf) to combine the individual files into one combo graph
run the combo graph through neato -n2 -Tpng >mycombo.png (see https://www.graphviz.org/faq/#FaqDotWithCoords)
gvpack -array_ib1 myfiles*.dot |neato -Tpng -n2 >oooo.png
OR
use invisible edges to connect the nodes from one cluster to another a->C. Unfortunately, this quickly becomes tedious, trying to get all the nodes to line up as you want.
I have two graphs being rendered by dot:
graph G {
graph[rankdir=LR]
node[shape=circle, fontname="Courier-Bold", fontsize=10, width=0.4, height=0.4, fixedsize=true]
edge[arrowsize=0.6, fontname="Courier-Bold", fontsize=10, arrowhead=vee]
v0 -- i0 [label=11]
v1 -- i0 [label=2]
v2 -- i0 [label=10]
i0 -- i1 [label=4]
i1 -- i2 [label=3]
i2 -- v3 [label=3]
i2 -- v4 [label=4]
i1 -- v5 [label=0, style=dashed]
}
graph G {
graph[rankdir=LR]
node[shape=circle, fontname="Courier-Bold", fontsize=10, width=0.4, height=0.4, fixedsize=true]
edge[arrowsize=0.6, fontname="Courier-Bold", fontsize=10, arrowhead=vee]
subgraph cluster_two {
fontname="Courier-Bold"
fontsize=10
v0 -- i0 [label=11]
v1 -- i0 [label=2]
v2 -- i0 [label=10]
i0 -- i1 [label=4]
i1 -- i2 [label=3]
i2 -- v3 [label=3]
i2 -- v4 [label=4]
i1 -- v5 [label=0, style=dashed]
}
}
The 2nd graph is exactly the same as the first, except that it's wrapped in subgraph. For whatever reason, the subgraph wrapping makes it so that node separation is much wider than normal:
The nodesep attribute doesn't control the nodes under a subgraph. Is there anything to get node placement to unstretch back to normal (as in the 1st picture)?
Ranksep is the attribute that sets the distance from one rank to the next. Ranksep is a graph-level attribute. When it is set, it applies to the entire graph. This is also true for nodesep, except nodesep sets the distance between two adjacent nodes on the same rank.
p.s. 2.40.1 is a rather old release. Many fixes have been applied over the last 18 months or so (I take no credit).
I have a dot file in which I create subgraph clusters which I want to appear in a specific order, let's say I have this:
digraph G {
splines=true;
sep="+25,25";
overlap=scalexy;
nodesep=0.6;
subgraph cluster_2 {
label="ADD_MORE_PROBLEMS";
subgraph cluster_3 {
label="pattern";
N1 [label="problem"];
}
subgraph cluster_4 {
label="replacement";
N2 [label="problem"];
N3 [label="problem"];
}
}
}
Which creates:
How do I ensure that "pattern" appears to the left of "replacement" (I may have an arbitrary number of subgraphs).
Clusters are one of the odd cases where simply the ordering in the code makes most (if not quite all) of the difference. If we simply reorder your code like this:
digraph G {
splines=true;
sep="+25,25";
overlap=scalexy;
nodesep=0.6;
subgraph cluster_2 {
label="ADD_MORE_PROBLEMS";
subgraph cluster_4 {
label="replacement";
N2 [label="problem"];
N3 [label="problem"];
}
subgraph cluster_3 {
label="pattern";
N1 [label="problem"];
}
}
}
that makes all the difference.
Now, that can fail, in which case setting up invisible edges is one of the more common solutions.
I can't give and answer, but can provide some clarification. The usual approach to force layout is to introduce hidden edges. In this case, it does not work.
Without the nested clusters, you can use rank=same to force connected edges onto the same level. Then, an invisible edge N1 -> N2 [style = invis] would force the nodes into the correct ordering.
However, constraining nodes with rank breaks the cluster membership and prevents the scheme from working.
The modified graph shows the result. There may not be a general solution.
digraph G {
splines=true;
sep="+25,25";
overlap=scalexy;
nodesep=0.6;
subgraph cluster_2 {
label="ADD_MORE_PROBLEMS";
subgraph cluster_3 {
label="pattern";
N1 [label="problem 1"];
}
subgraph cluster_4 {
label="replacement";
N2 [label="problem 2"];
N3 [label="problem 3"];
}
// Introduce hidden edge (shown dashed)
N1 -> N2 [style = dashed];
// Force nodes to remain at same rank
{ rank = same; N1; N2; }
}
}
I am trying to paint a little graph in GraphViz/dot.
The boxes "Team 1", "Turnier32" and "Team 2" should be on one horizontal level.
"Team 1" points right to "Turnier32", "Team 2" to the left.
I want the ellipses "Name1", "2015-11-14" and "Name2" below the corresponding nodes. There should only be straight horizontal and vertical edges.
My current approach is this:
digraph turnier{
ordering=out ;
subgraph {
rank=same;
T1 [shape="box", label="Team 1"];
TOURNAMENT [shape="box", label="Turnier32"];
T2 [shape="box", label="Team 2"];
}
subgraph {
rank=same;
N1 [shape="ellipse", label="Name1"];
DATE [shape="ellipse", label="2015-11-14"];
N2 [shape="ellipse", label="Name2"];
}
T1 -> N1 [label="hasName"];
TOURNAMENT -> DATE [label="occuredOnDate"];
T2 -> N2 [label="hasName"];
T1 -> TOURNAMENT [label="attended"];
T2 -> TOURNAMENT [label="attended"];
}
GraphViz reordered T1, TOURNAMENT and T2 to T1, T2, TOURNAMENT, which is not, what I want. If i strike out the last two edges, the order is correct.
Simply add to your last line constraint=false:
T2 -> TOURNAMENT [label="attended", constraint=false];
I am trying to create a tree structure with graphviz. I am open to either writing the graphviz code by hand or using the ruby-graphviz gem for ruby. Given the below picture can anyone provide any insight on the necessary code? Ignore that the lines are not straight...they should be when graphviz builds the graph. I am open to having dots/points when lines intersect as well.
I have played with ruby-graphviz and the family tree class...this is getting me part of the way there but I really need all lines to be straight and intersect at right angles and the out-of-the-box code doesn't seem to do that.
The code should be generic enough to allow for the "C" box to have children as well and for there also to be more children under "A".
The colors are irrelevant...the examples can exclude any coloring.
http://docs.google.com/drawings/pub?id=1lUTfgKP_LN0x7C3ItbsFjfLBuDTL84AtmoaW7YFn32Y&w=1036&h=713
A little late, I know, but I just wanted to show an other version without having to figure out the exact positions of each node.
digraph {
splines=false;
ranksep=0.05;
node[shape=box, color=lightblue, style=filled];
A;B;C;D;E;
node[shape=none, color=none, style=solid];
i1[label="Item 1"];
i2[label="Item 2"];
i3[label="Item 3"];
node[label="", width=0, height=0];
edge[arrowhead=none, color=blue];
{rank=same; n2; n1; n3;}
n2; n1; n3;
A -> n1;
n2 -> n1 -> n3;
{rank=same; B; C;}
n2 -> B;
n3 -> C;
{rank=same; n4; D;}
B -> n4 -> D;
{rank=same; n6; n5; i1;}
D -> n5 -> i1;
n4 -> n6;
{rank=same; n7; E;}
n6 -> n7 -> E;
{rank=same; n8; i2;}
E -> n8 -> i2;
{rank=same; n9; i3;}
i2 -> n9 -> i3;
}
Straight lines are enforced by:
splines=false - say no to splines
invisible nodes (nodes n1, n2,... n9)
placing nodes on the same rank with rank=same
It's still some work to get the dot file right, but it beats imho calculating yourself the position of each node.
Output looks like this:
As long as C has no child nodes, you'd have to apply some more trickery (invisible nodes) to display it all the way to the right.
In order to get a more general solution for different graphs, some further adaptations will probably be needed (apply weight to vertical edges, or group nodes which have to be vertically aligned, or use subgraphs, ...).
As far as I know this requires a little work-around; I will only do it in Graphviz DOT language. I give you the solution first, then provide some explanations of how you can extend it.
This is the resulting figure:
This is the Graphviz code producing the figure:
graph atree {
Item1 [shape=none,label="Item 1",pos="2.2,1.1!"];
Item2 [shape=none,label="Item 2",pos="2.2,0.1!"];
Item3 [shape=none,label="Item 3",pos="2.9,-0.3!"];
A [shape=box,color=lightblue,style=filled,pos="2,3!"];
B [shape=box,color=lightblue,style=filled,pos="1,2.1!"];
C [shape=box,color=lightblue,style=filled,pos="3,2.1!"];
D [shape=box,color=lightblue,style=filled,pos="1.5,1.5!"];
E [shape=box,color=lightblue,style=filled,pos="1.5,0.5!"];
D0 [style=invisible,fixedsize=true,width=0,height=0,pos="2,2.5!",label=""];
D1 [style=invisible,fixedsize=true,width=0,height=0,pos="1,2.5!",label=""];
D2 [style=invisible,fixedsize=true,width=0,height=0,pos="3,2.5!",label=""];
D3 [style=invisible,fixedsize=true,width=0,height=0,pos="1,1.5!",label=""];
D4 [style=invisible,fixedsize=true,width=0,height=0,pos="1,0.5!",label=""];
D5 [style=invisible,fixedsize=true,width=0,height=0,pos="1.5,1.1!",label=""];
D6 [style=invisible,fixedsize=true,width=0,height=0,pos="1.5,0.1!",label=""];
D7 [style=invisible,fixedsize=true,width=0,height=0,pos="2.2,-0.3!",label=""];
A -- D0 -- D1 -- B -- D3 -- D4 -- E [color=blue];
E -- D6 -- Item2 -- D7 -- Item3 [color=blue];
D0 -- D2 -- C [color=blue];
D3 -- D -- D5 -- Item1 [color=blue];
}
If you put it in a file named inputfile.dot you can get the resulting image file by using the command neato -Tpng inputfile.dot > outfile.png.
Now a couple of comments on how it works: The code building the tree with A, B, C, D, E, Item1, Item2, Item3 is straightforward (the attributes merely set the colors and box styles). The trick to get the lines straight and orthogonal consists of 1) adding invisible nodes with zero size to the graph, and 2) positioning all objects in absolute coordinates on the canvas. The auxiliary nodes D1, D2, D3, D4, D5, D6, D7 are needed for step 1) and the pos="x,y!" options are needed for step 2). Note, that you need the ! sign at the end of the pos command since otherwise the positions would not be considered final and the layout would still get changed.
You can add additional nodes by first positioning a new node (by using the code for the nodes A ... Item3 as a template), adding an invisible, auxiliary node (with pos such that all connections to and from it are orthogonal) and then adding the connection to the graph via <StartingNode> -- <AuxiliaryNode> -- <NewNode>.
Still another version using splines=ortho, which needs less hidden nodes and gives similar visual result.
digraph example {
splines=ortho;
ranksep=0.05;
node[shape=box, color=lightblue, style=filled];
A;B;C;D;E;
node[shape=none, color=none, style=solid];
i1[label="Item 1"];
i2[label="Item 2"];
i3[label="Item 3"];
node[label="", width=0, height=0];
edge[arrowhead=none, color=blue];
n1; n2; n3; n4; n5;
{rank=same; B; C;}
A -> n1;
n1 -> B;
n1 -> C;
{rank=same; n2; D;}
B -> n2;
n2 -> D;
{rank=same; n3; i1;}
D -> n3;
n3 -> i1;
{rank=same; n4; E;}
n2 -> n4;
n4 -> E;
{rank=same; n5; i2;}
E -> n5;
n5 -> i2;
{rank=same; n6; i3;}
i2 -> n6;
n6 -> i3;
}