Positioning nodes in a subgraph

I am working to order the positioning of nodes within a subgraph. The syntax that I have found online is as follows:

subgraph cluster_0{
       node[shape ="rectangle" pos="0,0!"] "name0";
       node[shape ="rectangle" pos="1,0!"] "name1";
       node[shape ="rectangle" pos="2,0!"] "name2";
}

I am expecting to get a subgraph with nodes name0, name1, & name2 to appear left to right in that order. Is this not how to specify the positioning of nodes in a subgraph by pos= “x_val, y_val!”?

(Hmm, the forum software seems to have problems with the letter l. Go figure)

  • dot ignores the pos attribute, only neato & fdp use this attribute. The documentation pos | Graphviz is NOT clear, sorry. (I’ll create an issue)
  • This: node[shape ="rectangle" pos="0,0!"] really says “for all following nodes, set the shape & pos”. A better way is "name0" [shape ="rectangle" pos="0,0!"] (though pos will be ignored)
  • To get three nodes horizontally positioned within a cluster, try:
digraph ok {
  subgraph cluster_0{
     { rank=same  // all nodes on same rank
       node [shape ="rectangle"]    // for all nodes in this subgraph
       edge [style=invis]           // for all edges, invisible links
       // we use the invisible edges to establish their sequence (kludge)
       name0 ->  name1 ->  name2 
     }
  }
}

Giving:
threeNodes

Here is a good reference: https://www.graphviz.org/pdf/dotguide.pdf

1 Like

thank you for the suggestion!! Is there any way to specify the vertical positioning?

Vertical positioning (ranking) is implied via edge definitions.
a->b will position a somewhere above b.
Note that if rank=same then a and b would be on the same rank (same Y value)

I have been able to created the layers of nodes using the a->b and b->c formatting. Then i set the edges connecting the nodes to be invisible. One problem that I see is that the distance from b->c is much smaller than the distance a->b. I would like to set the length of the edges to both be the smaller distance, so my diagram is a bit more condensed. I only see a minlen attribute. Is there any way that I can set the length of the edge to a particular value to constrain the max length and not only the minlen? Or would it make more sense to use the ranking functionality, that I have not been able to figure out?

What problem are you seeing?

Is there a max distance attribute or setting for the distances between two nodes? There only appears to be a constraint on min distance. This way the nodes are not positioned too far apart

It/something was capitalizing l’s when embedded in preformatted text. Seemingly all good now. Another mystery for the ages.

lmnop

Please include your source text.

subgraph cluster_1 {
A-> B
B-> C
}
the distance between A->B is significantly longer than the distance between B-> C. How can there be a max distance set to constraint the edge distances on the upperbound? There is a minlen attribute for the lower bound

I am not seeing your problem.

digraph I {
  subgraph cluster_1 {
  A-> B
  B-> C
  }
}

Gives:
edgeLength0

I used A, B, & C in place of the project names that I am using in my diagram. Hoping that the two edges would be enough to illustrate my point. I will have to check with my team to see if I am allowed to share the visual for security reasons. There are two subgraphs that have this issue and there are 14 and 6 nodes in each. Could this be because the subgraphs have a large number of nodes?

Probably not due to node counts.
A guess: maybe you are seeing the side-effects of “tall” nodes - nodes with greater heights. One “tall” node will impact the position of every node in the same rank. If this seems to be what is happening to your graph, either find a way to reduce the height of the “tall” nodes, or increase the distance between every rank using ranksep (ranksep | Graphviz) (probably not what you want)
There is a program available that will “anonymize” your source. Let me know if you want a copy.

Improving the consistency of node heights does fix my issue on creating equal spacing between nodes in a subgraph. One other question, can rank only set the positioning of nodes in the horizontal direction and also is rank only used for nodes and not subgraphs? I would like to set the order of subgraphs from left to right in my digraph

Rank only applies to one direction - normally horizontal, but vertical if rankdir=LR or rankdir=RL (rankdir | Graphviz).
Also, rank only applies to nodes, clusters just are fitted around their nodes (grossly simplified).
(Note: here, the term cluster is more appropriate than subgraph. Clusters a type of subgraph. Kind of).
Clusters are harder to position than nodes. To reposition a cluster, you need to reposition and/or change the nodes and edges they contain. (Yes, this is a common complaint/issue. Me, too)
To change cluster positions try:

  • Invisible edges (often, this will solve the problem)
  • invisible nodes
  • nesting clusters (peripheries=0 to remove the box around a cluster)
  • group attribute (for nodes)
  • weight attribute (for edges)
  • constraint attribute (for edges)
  • newrank attribute

Section 2.6 of https://www.graphviz.org/pdf/dotguide.pdf talks about positioning nodes & edges.

(For completeness, there are ways to explicitly position clusters, but it requires some real programming & lots of digging into the documentation)

I have defined the nodes in the subgraph as follows:

subgraph cluster_vertical_example{
node[]"Node1";
node[]"Node2";
node[]"Node3";
node[]"Node4";
node[]"Node5";

"Node2"-> "Node3"; 
"Node3"-> "Node4";

{rankdir=LR rank=same; "Node2"; "Node3"; "Node4";}
"Node4"->"Node5"
}

How come Nodes 2-4 do not appear vertically?

Why did you expect them to appear vertically?

In a previous response you had mentioned that the nodes should appear horizontally by default.

I have used the rankdir=LR vertical setting that is supposed to make the nodes appear vertically by:

{rankdir=LR rank=same; "Node2"; "Node3"; "Node4";}

I have also tried setting compound=true; on both the subgraph and digraph levels. Unfortunately, the positions appear scattered and I can not find away to horizontally align some groups of node or clusters while other groups vertically.

rankdir (rankdir | Graphviz) only applies to the Root graph (to the entire graph), not a subgraph. In this case rankdir=LR will be silently ignored.

Maybe this is what you are after?

digraph N {
subgraph cluster_vertical_example{

  "Node2"-> "Node3"
  "Node3"-> "Node4"
  "Node4"->"Node5"
  // guessing what you want
  // position node1 to left of node2
  {rank=same   "Node1"-> "Node2" [style=invis]}
}
}

Giving:
notRankdir1