Graphviz/Python: Recoloring a single node after it has been generated

Viewed 2537

I am getting acquainted with graphviz within Python 2.7. Is it possible to change the properties of a single node after it has been drawn?

e.g.

from graphviz import Digraph
q = Digraph()
q.node('a')
q.node('b')
q.edge('a','b')

q

Output of simple graph

Is it possible to change the color of node 'b' after the fact? I am aware that I can set it at the time of generation by

q.node('b', color = 'blue')

But, I'd like to be able to change it after generating it.

This link Color a particular node in Networkx and Graphviz

suggests using the graph's .node property to update a dict

G.node[2]['fillcolor']='red'

By analogy, I tried

q.node['b']['color'] = 'blue'

which gives an error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-54-43b05071d09a> in <module>()
----> 1 q.node['b']['color'] = 'blue'

TypeError: 'instancemethod' object has no attribute '__getitem__'

I think this may be because I am not using networkx as in the previous case.

I've also read the graphviz docs at http://graphviz.org/content/attrs but none of my experiments have worked. I'm sure it is something straightforward but I am missing it...

--- Old Guy In The Club

4 Answers

One way to do it is by editing the graph object directly.

>>> from graphviztest import *
>>> import json
>>> dot = Digraph(comment='My graph', format='png')
>>> dot.node('A', 'hurr')
>>> dot.node('B', 'durr')
>>> dot.edge('A','B')
>>> print dot
// My graph
digraph {
    A [label=hurr]
    B [label=durr]
    A -> B
}
>>> print json.dumps(dot.__dict__, indent=2)
{
  "comment": "My graph", 
  "_encoding": "utf-8", 
  "name": null, 
  "edge_attr": {}, 
  "_format": "png", 
  "body": [
    "\tA [label=hurr]", 
    "\tB [label=durr]", 
    "\tA -> B"
  ], 
  "filename": "Digraph.gv", 
  "graph_attr": {}, 
  "strict": false, 
  "node_attr": {}
}
>>> dot.body[0] = '\tA [label=derp]'
>>> dot.body[1] = '\tB [label=blah]'
>>> print dot
// My graph
digraph {
    A [label=derp]
    B [label=blah]
    A -> B
}
>>> 


You could also save the resulting graph in SVG and edit the SVG directly, changing the color of a given node using CSS. In SVG, generated nodes have ids, making it easy to change the color (stroke attribute).

Related