1

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.

MHTB
  • 39
  • 5
  • Best to show a small complete MWE that indicates your problems i.e. an example with just a couple of nodes / edges. – albert Jan 05 '20 at 14:23
  • @albert You're right, but the whole point of my question is about using different shapes for nodes and if someone shows me how to do it for just two nodes, it suffices. – MHTB Jan 05 '20 at 14:57
  • As I don't know pygraphviz I cannot advise without seeing some code. In case I see some code I might give a clue (I expect that either each node has also an attribute shape or otherwise it is possible to set first the node shape for e.g. the double circle nodes and after this for the circle nodes (analogous to the example in the documentation you mentioned (and the gv file mentioned there). – albert Jan 05 '20 at 15:39
  • Have a look at the documentation http://pygraphviz.github.io/documentation/pygraphviz-1.5/tutorial.html#nodes-and-edges, I think under the heading Attributes there is exactly the information required (and I was pointing at even without doing a simple Google search for "graphviz documentation). – albert Jan 05 '20 at 15:43

2 Answers2

1

All the information is contained in the pygraphviz documentation (http://pygraphviz.github.io/documentation/pygraphviz-1.5/tutorial.html#nodes-and-edges) in the paragraph Attributes where it states:

To set the default attributes for graphs, nodes, and edges use the graph_attr, node_attr, and edge_attr dictionaries

G.graph_attr['label']='Name of graph' G.node_attr['shape']='circle' G.edge_attr['color']='red'

Graph attributes can be set when initializing the graph

G=pgv.AGraph(ranksep='0.1')

Attributes can be added when adding nodes or edges,

G.add_node(1, color='red') G.add_edge('b','c',color='blue')

or through the node or edge attr dictionaries,

n=G.get_node(1) n.attr['shape']='box'

e=G.get_edge('b','c') e.attr['color']='green'

albert
  • 8,285
  • 3
  • 19
  • 32
1

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')
pooya
  • 26
  • 3