Adds methods to draw PetriNet and StateGraph instances using
GraphViz.
For example, let's first define a Petri net:
>>> import snakes.plugins
>>> snakes.plugins.load('gv', 'snakes.nets', 'nets')
<module ...>
>>> from nets import *
>>> n = PetriNet('N')
>>> n.add_place(Place('p00', [0]))
>>> n.add_transition(Transition('t10'))
>>> n.add_place(Place('p11'))
>>> n.add_transition(Transition('t01'))
>>> n.add_input('p00', 't10', Variable('x'))
>>> n.add_output('p11', 't10', Expression('x+1'))
>>> n.add_input('p11', 't01', Variable('y'))
>>> n.add_output('p00', 't01', Expression('y-1'))
Thanks to plugin gv, we can draw it using the various engines of
GraphViz; we can also draw the state graph:
>>> for engine in ('neato', 'dot', 'circo', 'twopi', 'fdp') :
... n.draw(',test-gv-%s.png' % engine, engine=engine)
Graph(...)
Graph(...)
Graph(...)
Graph(...)
Graph(...)
>>> s = StateGraph(n)
>>> s.build()
>>> s.draw(',test-gv-graph.png')
The plugin also allows to layout the nodes without drawing the net
(this is only available for PetriNet, not for StateGraph). We
first move every node to position (-100, -100); then, we layout the
net; finally, we check that every node has indeed been moved away from
where we had put it:
>>> for node in n.node() :
... node.pos.moveto(-100, -100)
>>> all(node.pos.x == node.pos.y == -100 for node in n.node())
True
>>> n.layout()
>>> any(node.pos.x == node.pos.y == -100 for node in n.node())
False
layout is here just in the case you
would need a layout of your nets.
pos and clusters (that are automatically
loaded)
Extensions
Class PetriNet
class PetriNet (module.PetriNet) :
An extension with methods draw and layout
Method PetriNet.draw
def draw (self, filename, engine="dot", debug=False,
graph_attr=None, cluster_attr=None,
place_attr=None, trans_attr=None, arc_attr=None) : ...
Draw the Petri net to a picture file. How the net is
rendered can be controlled using the arguments ..._attr.
For instance, to draw place in red with names in
uppercase, and hide True guards, we can proceed as
follows:
>>> import snakes.plugins
>>> snakes.plugins.load('gv', 'snakes.nets', 'nets')
<module ...>
>>> from nets import *
>>> n = PetriNet('N')
>>> n.add_place(Place('p'))
>>> n.add_transition(Transition('t'))
>>> n.add_input('p', 't', Value(dot))
>>> def draw_place (place, attr) :
... attr['label'] = place.name.upper()
... attr['color'] = '#FF0000'
>>> def draw_transition (trans, attr) :
... if str(trans.guard) == 'True' :
... attr['label'] = trans.name
... else :
... attr['label'] = '%s\n%s' % (trans.name, trans.guard)
>>> n.draw(',net-with-colors.png',
... place_attr=draw_place, trans_attr=draw_transition)
Graph(...)
Call API
str filename: the name of the image file to createstr engine: the layout engine to use:'dot'(default),'neato','circo','twopi'or'fdp'object debugobject graph_attrcallable cluster_attr: a function to format clusters of nodes, it will be called with the cluster and its attributes dict as parameterscallable place_attr: a function to format places, it will be called with the place and its attributes dict as parameterscallable trans_attr: a function to format transitions, it will be called with the transition and its attributes dict as parameterscallable arc_attr: a function to format arcs, it will be called with the label and its attributes dict as parameters
Method PetriNet.layout
def layout (self, xscale=1.0, yscale=1.0, engine="dot",
debug=False, graph_attr=None, cluster_attr=None,
place_attr=None, trans_attr=None, arc_attr=None) : ...
Layout the nodes of the Petri net by calling GraphViz
and reading back the picture it creates. The effect is to
change attributes pos (see plugin pos) for every node
according to the positions calculated by GraphViz.
Call API
float xscale: how much the image is scaled in the horizontal axis after GraphViz has done the layoutfloat yscale: how much the image is scaled in the vertical axis after GraphViz has done the layoutstr engine: the layout engine to use:'dot'(default),'neato','circo','twopi'or'fdp'object debugobject graph_attrcallable cluster_attr: a function to format clusters of nodes, it will be called with the cluster and its attributes dict as parameterscallable place_attr: a function to format places, it will be called with the place and its attributes dict as parameterscallable trans_attr: a function to format transitions, it will be called with the transition and its attributes dict as parameterscallable arc_attr: a function to format arcs, it will be called with the label and its attributes dict as parameters
Class StateGraph
class StateGraph (module.StateGraph) :
An extension with a method draw
Method StateGraph.draw
def draw (self, filename, engine="dot", debug=False,
node_attr=None, edge_attr=None, graph_attr=None) : ...
Draw the state graph to a picture file.
Call API
Noneorstr filename: the name of the image file to create orNoneif only the computed graph is neededstr engine: the layout engine to use: 'dot' (default), 'neato', 'circo', 'twopi' or 'fdp'object debugcallable node_attr: a function to format nodes, it will be called with the state number, theStateGraphobject and attributes dict as parametersobject edge_attr: a function to format edges, it will be called with the transition, its mode and attributes dict as parameterscallable graph_attr: a function to format grapg, it will be called with the state graphe and attributes dict as parameters