Regarding the answer to the link you provided, it lists the attributes: nslimit
, nslimit1
, mclimit
for dot
layout engine, and maxiter
for neato
or fdp
layout engines; and attribute splines
.
By default your code uses dot
layout engine as described in documentation. If the choice of engine is not important to you, then for example neato
gives almost 10 times acceleration (according to my observations), to use it (or to use the other engines such as circo
or twopi
, that are listed in the link that you pointed out in your question) you can see an example in the documentation:
import graphviz
g = graphviz.Graph(engine='neato')
# You can also change engine attribute on existing instance:
g.engine = 'circo'
To use the attributes nslimit
, nslimit1
and etc, in your code, you can look in the GraphViz documentation to which object (Graph, Node or Edge) the attribute belongs (for example about nslimit
, cite: Valid on: Graphs) and write it in your code according to the python graphviz library's documentation:
import graphviz
ps = graphviz.Digraph('pet-shop',
graph_attr={'nslimit': '0',
'nslimit1': '2'},
node_attr={'shape': 'plaintext'},
edge_attr={'color': 'black'})
For example, I will replace the line dot = Digraph(format="png")
with:
dot = Digraph(format="png",
engine='neato', # Layout engine.
graph_attr=dict(splines='true',
sep='5',
overlap='scale'),
node_attr=dict(shape='circle',
margin='0',
fontsize='10',
width='0.2',
height='0.2',
fixedsize='true'),
edge_attr=dict(arrowsize='0.4'))
and get result (34 seconds, 55 MB, posted a thumbnail):

I recreated MWE from your example for testing:
from graphviz import Digraph
import random
nodes = 100 # 50 can be used for test purposes, to reduce time.
outgoing_edges = 40 # Because 40 edges * 100 nodes = 4000 edges
class G:
def __init__(self):
self.graph = {}
# Fill graph with randomly generated data:
for node in range(nodes):
self.graph[node] = random.sample(range(nodes), outgoing_edges)
def letter(self, key):
return str(key)
def draw_graph(self):
dot = Digraph(format="png")
edges = set()
for k, v in self.graph.items():
dot.node(self.letter(k))
for neighbor in v:
edge = self.letter(k) + "_" + self.letter(neighbor)
if edge not in edges:
edges.add(edge)
# dot.edges(list(edges))
for edge in edges:
dot.edge(*edge.split("_"))
dot.render('og.gv', view=True)
g = G()
g.draw_graph()
You can measure the speed of dot.render()
with timeit
:
import timeit
start_time = timeit.default_timer()
func1()
print(timeit.default_timer() - start_time)