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 debug
object graph_attr
callable 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 debug
object graph_attr
callable 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
None
orstr filename
: the name of the image file to create orNone
if only the computed graph is neededstr engine
: the layout engine to use: 'dot' (default), 'neato', 'circo', 'twopi' or 'fdp'object debug
callable node_attr
: a function to format nodes, it will be called with the state number, theStateGraph
object 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