pydot
uses the same name-based approach to identifying graph items as graphviz
. However we would rather use python objects. Therefore, we patch pydot
to use unique names.
g = Dot()
a = Node('a')
g.add_node(a)
g
If a 2-tuple is passed to add_node
, then the 2nd element becomes the tooltip. You can also pass any kwargs
that are accepted by graphviz
.
g = Dot()
g.add_node(Node(['a', "My tooltip"], fillcolor='pink'))
g
Keyword args can also be arbitrary functions, which will called with the node's label.
g = Dot()
o = 'a'
g.add_node(Node(o, fillcolor=lambda o:'pink'))
g
object2graph(o).get_fillcolor()
The callable kwargs functionality can be used to map labels to colors in a consistent way..
graph_colors1 = partial(obj2node_color, plt.get_cmap('rainbow'), 30, 160)
graph_colors2 = partial(obj2node_color, plt.get_cmap('tab20'), 30, 160)
These predefined color mapping functions provide a good range of colors and readable text.
g = Dot()
g.add_node(Node('a', fillcolor=graph_colors1))
g.add_node(Node('b', fillcolor=graph_colors1))
g
g = Dot()
g.add_node(Node('a', fillcolor=graph_colors2))
g.add_node(Node('b', fillcolor=graph_colors2))
g
We'll use the former color function as our default. You can change it by simply modifying node_defaults
.
g = Dot()
sg = Cluster('clus', tooltip='Cluster tooltip')
sg.add_node(Node(['a', "My tooltip"]))
sg.add_node(Node('b'))
g.add_subgraph(sg)
g
You can subscript into a Graph
's Node
s by index:
print(sg[0].get_label())
There's no good reason to have different methods for adding clusters vs nodes (as pydot
requires), so we provide a single method.
g = Dot()
sg = Cluster('clus')
g.add_item(sg)
sg.add_item('a')
g
sg1 = Cluster('clus')
sg1.add_items('n1', 'n2')
sg2 = Cluster()
sg2.add_item('n')
graph_items(sg1,sg2)
sg2 = Cluster('clus2')
n1 = sg2.add_item('n1', fillcolor='pink')
n2 = sg2.add_item('n2', fillcolor='lightblue')
sg2.add_item(n1.connect(n2))
sg1 = Cluster('clus1')
sg1.add_item(sg2)
a,b = Node('a'),Node('b')
edges = a.connect(b),a.connect(a),sg1.connect(b),sg2[0].connect(a)
g = Dot()
g.add_items(sg1, a, b, *edges)
g
This is a shortcut for creating connections between objects that are already in a graph.
a,b = 'a','b'
g = graph_items(a, b)
g.add_items(*object_connections([(a,b)]))
g
Since it's common to want to connect a series sequentially, we provide some simple shortcuts for this functionality.
g = Dot()
its = g.add_items('a','b','c')
g.add_edges_seq(its)
g
g = Dot()
g.add_item(seq_cluster(['a','b','c'], 'clust'))
g.add_item(seq_cluster(['1','2','c'], 'clust2'))
g
g = Dot()
g.add_item(seq_cluster(['a','b','c'], 'clust'))
g
sg1 = seq_cluster(['a','b','c'], 'clust1')
sg2 = seq_cluster(['a1','a2',sg1], 'clust2')
g = Dot()
g.add_item(sg2)
g
sg1 = seq_cluster(['inp'], 'clust1')
sg2 = seq_cluster(['a','b','c'], 'clust2')
sg2.add_items(sg1.connect(sg2[-1]), sg1.connect(sg2))
g = Dot()
g.add_items(sg1,sg2)
g
sg = Cluster('clus')
a,b,c = sg.add_items('a','b','c')
p = sg.add_item(Point())
sg.add_item(p.connect(c))
sg.add_items(p.connect(a), a.connect(b), b.connect(c))
g = Dot()
g.add_items(sg)
g