0

I have a tree which I plot with Graphviz, however the distances between the nodes is very large and not efficiently used. Can this be improved? enter image description here

I tried playing with mindist, splines and overlap, but nothing seems to work. Is this the best graphviz is able to do?

The data:

https://pastebin.com/JUC7GhLV

The code:

import json
import pygraphviz as pgv
# Read data from the "graph1.json" file
with open("graph2.json") as f:
    edges_data = json.load(f)

# Create a new directed graph
graph = pgv.AGraph(strict=False, directed=True)

# Add nodes and edges to the graph based on the JSON data
for edge in edges_data:
    graph.add_node(edge["ID"])
    if edge["ParentID"]:
        graph.add_edge(edge["ParentID"], edge["ID"])

graph_attrs = {
    'dpi': 50, 
    'root': 10000185, 
    'mindist': 0.1
#    'splines': False,   # false 
#    'overlap':'scale'    # false
}

graph.graph_attr.update(graph_attrs)
graph.draw("output_graph.svg", prog="circo", format="svg")
WG-
  • 1,046
  • 2
  • 14
  • 27
  • A smaller sample input and output would be easier to reproduce - can you provide a [example] without downloading and rendering 4973 nodes ? – hc_dev Jul 29 '23 at 20:39
  • Well with a smaller example you do not have the issue naturally... It is only 281.62 KB data and rendering goes in ~5 sec. – WG- Jul 29 '23 at 21:02
  • The advice and principle of [example] is not about performance or volume, rather than reducing complexity, simplicity and to focus on the essential. What is the "natural" issue here? Is it the space that is required to layout the tree, for all the branches unfolding from root and their recursive sub-branches to not overlap ? Where should we reduce the edge-length then, and what would be efficient ? – hc_dev Jul 29 '23 at 21:12

2 Answers2

1

Edge length attribute

Graphviz has the attribute len:

Preferred edge length, in inches

But:

Note: neato, fdp only.

See also: How to specify the length of an edge in graphviz?.

Example with 2 inches

So, you can add:

graph.edge_attr["len"] = 2  # Preferred edge length, in inches, works only with layout-engines neato or fdp
graph.draw("output_graph.png", prog="neato")

Setting the preferred edge length of 2 inches, the output of given 4973 nodes rendered by neato engine becomes an illegible, overlapping snowflake like in this picture:

snowflake with edges of 2 inches length

Example with 4 inches

Another attempt with 4 inches produces:

snowflake with edge-length 4 inches

Note: the rendering took longer, also the file size increased from the 2-inches PNG's 2.2M to 15M.

Example with 6 inches

The text is still not readable with 6 inches edge-length:

snowflake with edge-length 6 inches

Now we have reached 22M for the PNG.

hc_dev
  • 8,389
  • 1
  • 26
  • 38
  • Yes knew about the length property but that approach indeed as you also shown I already cut of because I thought it would make it infeasable, circo provides the best results, however it just has to much inside spacing. So I will simply edit the graph by hand. – WG- Jul 30 '23 at 12:22
1

You have probably hit this circo bug:

Trying to find a circo work-around will probably not lead to success (unless you feel lucky)
Try the other layout engines, twopi, neato, fdp, and dot

hc_dev
  • 8,389
  • 1
  • 26
  • 38
sroush
  • 5,375
  • 2
  • 5
  • 11
  • Thank you for your addition. Indeed it sure does look like the same issue indeed. Tried other layout engines but none give a nice viewable graph unfortunatly. – WG- Jul 30 '23 at 12:21