Graphviz graph positioning xlabels
Asked Answered
G

3

36

I have tried using xlp and also followed this graphviz thread (http://www.graphviz.org/content/how-use-xlp-attribute-positioning-external-labels-xlabel), but neither have actually worked.

This is my dot code:

digraph {
    forcelabels=true;
    rankdir=LR;
    graph[ranksep=1,nodesep=.5];
    node[shape=box];
    "start" [xlabel="start",xlp="0,0",shape=doublecircle,label=" "];
    "requested"->"fault";
    "requested"->"progress";
    "start"->"requested";
    "progress"->"fault";
    "progress"->"progress";
    "progress"->"complete";
    "fault" [xlabel="fault",shape=doublecircle,label=" "];
    "complete" [xlabel="complete",shape=doublecircle,label=" "];
}

And this is what it looks like: enter image description here

Ideally start,fault, and complete would just be directly under the nodes, but I can't seem to postion the xlabels correctly.

Gavette answered 7/6, 2015 at 2:35 Comment(4)
I have the exact same problem, I also want to position labels under the nodes but there seems to be no tutorial or anything on how to do it.Additament
I tried xlabels, but their positioning seems to be brokenKatusha
I've been looking at the data generated by dot - and changing the xlp information doesn't seem to do anything cf. graphviz.org/content/… Likewise with changing the actual pos values.Forlini
I realise this comment is late to the party (and things may have changed) but in the docs it states in the table of attributes: xlp NE point write only. Then above that table it states: "write only indicates that the attribute is used for output, and is not used or read by any of the layout programs" which explains why setting it doesn't do anything.Holton
I
15

If you use neato with the -n2 flag, you should be able to set the position of xlabel. You would need to specify the position of every node, though.

So if you had a file called lb.gv with the following contents:

digraph{
    forcelabels=true;
    rankdir=LR;
    graph[ranksep=1,nodesep=.5,margin=0.3,bgcolor=Transparent];

    node[shape=box];
    start [pos="0,0", xlp="23,54", xlabel=start, shape=doublecircle, label= " "];
    requested [pos="100,0"];
    progress [pos="250,-66"];
    fault [pos="400,70", xlp="424,124", xlabel=fault, shape=doublecircle,label= " "];
    complete [pos="400,-66", xlp="424,-10", xlabel=complete, shape=doublecircle,label= " "];
    requested->fault;
    requested->progress;
    start->requested;
    progress->fault;
    progress:w->progress:_;
    progress->complete;
}

You could run neato -n2 -Tpng lb.gv > test.png

That's what I got:

graphviz

Ilana answered 29/11, 2016 at 15:1 Comment(4)
Note: this forces you to place everything explicitly, which is a pain, and half defeats the purpose of graphviz.Delouse
@CiroSantilli烏坎事件2016六四事件法轮功 That's a bummer indeed. That's why there is an open feature request ticket for it: graphviz.org/mantisbt/view.php?id=2410Ilana
I face the same problem, it seems that the feature to avoid to place everything explicitly is still not available ?Boucher
@IvanChaer the feature request is now gitlab.com/graphviz/graphviz/issues/299 and gitlab.com/graphviz/graphviz/issues/68Cowitch
D
4
  • Use newlines in label string to drop text below node
  • set fixedsize=true to keep node size to default
  • add cluster to keep lowest labels from being truncated
digraph {
    rankdir=LR;
    graph[ranksep=1,nodesep=.5];
    //  add a cluster to provide "margin" for labels below nodes
    subgraph cluster_space {
      graph [peripheries=0]
      node[shape=box];
      // dot ignores xlp
      // add newlines to shift label down
      // fixedsize=true to keep node sized correctly
      "start" [label="\n\n\n\nstart" shape=doublecircle fixedsize=true ];
      "requested"
      "progress"
      "complete" [label="\n\n\n\ncomplete" shape=doublecircle fixedsize=true]
      "fault" [label="\n\n\n\nfault" shape=doublecircle fixedsize=true]

      "requested"->"fault";
      "requested"->"progress";
      "start"->"requested";
      "progress"->"fault";
      "progress"->"progress";
      "progress"->"complete";
    }
}

Giving:
enter image description here

Dude answered 17/4, 2022 at 2:13 Comment(0)
B
2

Not exactly what you are asking, but you could try something like:

digraph nodes_as_labels {
    rankdir=LR;
    graph[ranksep=1,nodesep=.5];
    node[shape=box];

    "start" [xlp="0,0",shape=doublecircle,label=" "];
    "fault" [shape=doublecircle,label=" "];
    "complete" [shape=doublecircle,label=" "];
    "startlabel" [label="start",penwidth="0"];
    "faultlabel" [label="fault",penwidth="0"];
    "completelabel" [label="complete",penwidth="0"];

    "startlabel" -> "start"[style="invis"];
    "requested"->"fault";
    "requested"->"progress";
    "start"->"requested";
    "progress"->"fault";
    "progress"->"progress";
    "progress"->"complete";
    "fault" -> "faultlabel"[style="invis"];
    "complete" -> "completelabel"[style="invis"];
}

This results in:

gv converted to png

This approach is more relevant when you are using the neato or fdp layout engine, because then you can use the len attribute to set the distance between the nodes that act as label and the nodes you are labeling. This way you can prevent the labels from overlapping edges. Unfortunately, the len attribute does not work for the dot layout engine that the example is using, which is why the labels in the result are far away from the nodes they are labeling.

Brader answered 16/4, 2022 at 23:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.