Forcing "main line" nodes into a straight line in Graphviz (or alternatives)
Asked Answered
E

2

26

I'm trying to use Graphviz dot (but am willing to use something else) to generate a graph with a long "main line" of nodes, and many small branches. I'd like the main line to be straight from left to right, with the small branches above or below it. However, Graphviz "balances" the two branches, so I end up with a crooked graph.

To illustrate, here's a sketch similar to what I currently get:

Current Graph

And this is what I actually want:

Wanted graph

Is there any way to force or encourage Graphviz to generate a graph like the second one? I may be able to use "dummy" second branches to have it do a 3-way layout, and then hide/delete the dummies afterward, but if there's a better option that would be preferable.

Epinephrine answered 12/1, 2011 at 16:31 Comment(0)
I
40

Here is a solution using the weight attribute of edges:

digraph G {
    rankdir="LR";
    node[width=0.15, height=0.15, shape=point];
    edge[weight=2, arrowhead=none];
    1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8;
    edge[weight=1];
    2 -> 9 -> 10 ;
    5-> 11 -> 12;
}

Result:

graphivz

Iluminadailwain answered 12/1, 2011 at 17:8 Comment(3)
That seems to do the trick, but it seems to require that the graph be directed. Mine was defined as undirected, but there's no particular reason it needs to be, so that should work. Thanks.Epinephrine
I'm not sure whether this would be possible as an undirected graph, but I'm glad this works for you.Iluminadailwain
The best way to create an undirected graph is use a directed graph but set edge[dir="none"]. Another options is dir="back", which uses the -> direction for graph layout but draws the arrow pointing the opposite direction.Galvin
I
39

A second solution using the group attribute of nodes - again a directed graph:

From the graphviz dot reference:

If the end points of an edge belong to the same group, i.e., have the same group attribute, parameters are set to avoid crossings and keep the edges straight.

So here we go:

digraph g{
    rankdir="LR";
    node[width=0.15, height=0.15, shape=point, group=main];
    edge[arrowhead=none];
    1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8;
    node[group=branches];
    2 ->  9 -> 10;
    5 -> 11 -> 12;
}

Output is exactly the same as in my first answer.

Iluminadailwain answered 12/1, 2011 at 20:20 Comment(1)
Thanks, I appreciate you giving an alternative solution, even though I had already accepted the other one. I'm still quite new to Graphviz, so it's nice to see the possible ways to achieve things like this.Epinephrine

© 2022 - 2024 — McMap. All rights reserved.