Search code examples
pythongraphvizpygraphviz

Nodes with different shapes in pygraphviz


I'm trying to visualize an automaton in pygraphviz, like the example in graphviz documentation:

Finite Automaton example in graphviz docs

I've found that node shapes can be changed like:

A.node_attr['shape']='circle' # A is a pygraphviz AGraph

This changes the shape of all nodes, but I want to use different node shapes for different nodes (some 'circle' and some 'doublecircle'). Any advice for doing that?

Note: I'm using pygraphviz because I want to use networkx graph objects and those can be converted to AGraph objects of pygraphviz. Also, apparently networkx can't produce graph visualizations like this.


Solution

  • Each node in the graph is an instance of Node class and nodes attributes are set with ItemAttribute. This means you can change the attributes of nodes separately. Thus, you only need to access the nodes. This is possible vs iternodes, an iterator on nodes of AGraph. Here's an example of using networkx and pygraphviz together and changing the node's attributes:

    import networkx as nx
    import pygraphviz as pgv
    
    G = nx.DiGraph()
    
    nodes = {'a', 'b', 'c'}
    edges = {('a', 'b'), ('b', 'c'), ('a', 'c')}
    
    G.add_nodes_from(nodes)
    G.add_edges_from(edges)
    
    A = nx.nx_agraph.to_agraph(G)
    
    shapes = ['circle', 'box']
    for i, node in enumerate(A.iternodes()):
            node.attr['shape'] = shapes[i%2]
    A.layout()
    A.draw('graph.png')