Search code examples
graphvizpygraphviz

evenly distribute pygraphviz nodes


I have a graphviz code like this:

        import pygraphviz as pgv
        A = pgv.AGraph(strict=False, directed=True,
                       overlap=False, sep="+10,10")
        [A.add_node(k) for k, v in S]  # adding all nodes

        A.add_edge(S.created, S.packaged_unassigned)
        A.add_edge(S.packaged_unassigned, S.packaged_assigned)
        A.add_edge(S.packaged_assigned, S.packaged_unassigned, style="dotted")
        A.add_edge(S.packaged_assigned, S.shipped_to_distributor)
        A.add_edge(S.shipped_to_distributor, S.on_distributor_side_out)
        A.add_edge(S.on_distributor_side_out, S.shipped_to_deployer)
        A.add_edge(S.shipped_to_deployer, S.on_distributor_side_in)
        A.add_edge(S.on_distributor_side_in, S.shipped_to_lab)
        A.add_edge(S.shipped_to_lab, S.on_lab_side)
        A.add_edge(S.on_lab_side, S.analysis_completed)
        A.add_edge(S.analysis_completed, S.completed)
        A.layout()
        A.draw("status_chart.png")

which produces this output: https://i.ibb.co/7pJQ8rd/Screenshot-2020-12-20-at-22-23-10.png

My concern here is that the nodes seem to not utilize the available space properly. Instead they just span the diagonal of the image. How can i make graphviz utilize the space better to create a smaller image while keeping the constraint of no overlaps?


Solution

  • One constraint is that you have specified a chained graph. and thus, the plot is somewhat constrained by that.

    See the documentation for some possible alternative options to specify:

    https://pygraphviz.github.io/documentation/latest/reference/agraph.html

    For example, you can try specifying a landscape view AGraph(landscape='true'...)

    You can also try experimenting with different layout directives:

    Optional prog=[‘neato’|’dot’|’twopi’|’circo’|’fdp’|’nop’] will use specified graphviz layout method.

    Also see:

    unflatten(args='')
    

    To adjust directed graphs to improve layout aspect ratio.

    Another technique you could use is to break-up parts of the graph, such that it might look like this (adding a text label to the nodes, with the numbering scheme):

    (1) -> (2) ->(3)
    (4) -> (5) ->(6)
    ...
    

    NOTE: The Python documentation for that library specifically suggests that you also refer to the Graphviz documentation...for additional options.

    http://www.graphviz.org/doc/info/lang.html

    http://www.graphviz.org/doc/info/attrs.html

    For example:

    http://www.graphviz.org/doc/info/attrs.html#d:ratio

    http://www.graphviz.org/doc/info/attrs.html#a:layout

    http://www.graphviz.org/doc/info/attrs.html#d:scale

    The Gallery also has some great examples, illustrating the use of different parameters

    http://www.graphviz.org/gallery/