示例#1
0
    def _dot(self, engine='fdp'):
        '''Generate dot representation (as object, not source).

        Requires graphviz module.

        Returns:
            string (SVG)
        '''
        try:
            from graphviz import Graph as gvGraph, Digraph as gvDigraph
        except:
            raise Exception('Missing module: graphviz')
        g = gvDigraph(engine=engine) if self.directed else gvGraph(
            engine=engine)
        for src in range(self.order):
            for dst in self.adjlists[src]:
                if self.directed or src <= dst:
                    g.edge(str(src), str(dst))
        return g
示例#2
0
 def _gvgraph_(self):
     def _gv_args(node):
         is_dict = isinstance(node, dict)
         return {
             'shape': 'none' if is_dict else 'box',
             'margin': '0' if is_dict else '.05'
         }
     def _tostr(node):
         if isinstance(node, dict):
             return ''.join(
                 ['<<FONT POINT-SIZE="12"><TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">'] +
                 ['<TR><TD>{}</TD><TD>{}</TD></TR>'.format(k, _escape(v)) for k, v in node.items() if not k.startswith('_thread_')] +
                 ['</TABLE></FONT>>'])
         return str(node)
     def walk(T):
         curr = self.node(G, _tostr(T.root), id(T), gv_args = _gv_args(T.root))
         if T.children:
             for child in T.children:
                 self.node(G, _tostr(child.root), id(child), gv_args = _gv_args(child.root))
                 self.edge(G, curr, id(child ))
             with G.subgraph(edge_attr = {'style': 'invis'}, graph_attr = {'rank': 'same'}) as S:
                 for f, t in zip(T.children, T.children[1:]):
                     self.edge(S, id(f), id(t))
             for child in T.children: walk(child)
     G = gvDigraph(
         graph_attr = {
             'nodesep': '.25',
             'ranksep': '.25'
         },
         node_attr = {
             'width': '0',
             'height': '0',
             'style': 'rounded, setlinewidth(.25)'
          },
          edge_attr = {
             'dir': 'none'
          }
     )
     self._nodes = set()
     walk(self)
     return G
示例#3
0
 def _gvgraph_(self):
     if self.G: return self.G
     sep = '\n' if self.large_labels else None
     G = gvDigraph(
             graph_attr = {
                 'rankdir': 'LR',
                 'size': '32'
             },
             node_attr = {'margin': '.05'} if self.large_labels else {},
             engine = 'dot'
         )
     if self.S is not None:
         self.edge(G,
             self.node(G, '', id(self.S), gv_args = {'shape': 'none'}),
             self.node(G, self.S, sep = sep, gv_args = {'peripheries': '2' if self.S in self.F else '1'})
         )
     for X, x, Y in self.transitions:
         self.edge(G,
             self.node(G, X, sep = sep, gv_args = {'peripheries': '2' if X in self.F else '1'}),
             self.node(G, Y, sep = sep, gv_args = {'peripheries': '2' if Y in self.F else '1'}),
             x, self.large_labels
         )
     self.G = G
     return G
示例#4
0
def displaySVG(ref, filename='temp'):
    """Render a graph to SVG format.

    *Warning:* Made for use within IPython/Jupyter only.

    Args:
        ref (Graph).
        filename (str): Temporary filename to store SVG output.

    Returns:
        SVG: IPython SVG wrapper object for graph.

    """

    # Ensure all modules are available
    try:
        from graphviz import Graph as gvGraph, Digraph as gvDigraph
        from IPython.display import SVG
    except:
        raise Exception("Missing module: graphviz and/or IPython.")
    # Traverse graph and generate temporary Digraph/Graph object
    output_format = 'svg'
    if ref.directed:
        graph = gvDigraph(filename, format=output_format)
    else:
        graph = gvGraph(filename, format=output_format)
    if ref is not None:
        for src in range(ref.order):
            src_id = 'node_' + str(src)
            graph.node(src_id, label=str(src))
            for dst in ref.adjlists[src]:
                if ref.directed or src >= dst:
                    graph.edge(src_id, 'node_' + str(dst))
    # Render to temporary file and SVG object
    graph.render(filename=filename, cleanup=True)
    return SVG(filename + '.' + output_format)
示例#5
0
    def _gvgraph_(self):
        if self.G is not None: return self.G
        derivation = self.derivation
        G = gvDigraph(
            graph_attr = {
                'nodesep': '.25',
                'ranksep': '.25'
            },
            node_attr = {
                'shape': 'box',
                'margin': '.05',
                'width': '0',
                'height': '0',
                'style': 'rounded, setlinewidth(.25)'
            },
            edge_attr = {
                'dir': 'none',
                'penwidth': '.5',
                'arrowsize': '.5'
            }
        )

        def remove_ε(sentence):
            return tuple(_ for _ in sentence if _[0] != ε)

        sentence = ((derivation.start, 0, 0), )
        for step, (rule, pos) in enumerate(derivation.steps(), 1):
            lhs, rhs = derivation.G.P[rule].as_type0()
            rhsn = tuple((X, step, p) for p, X in enumerate(rhs))
            sentence = remove_ε(sentence[:pos] + rhsn + sentence[pos + len(lhs):])
        last_sentence = set(sentence)

        use_levels = not self.compact

        sentence = ((derivation.start, 0, 0), )
        with G.subgraph(graph_attr = {'rank': 'same'}) as S:
            if use_levels: prev_level = self.node(S, ('LevelNode', 0), gv_args = {'style': 'invis'})
            self.node(S, sentence[0][0], hash(sentence[0]))

        for step, (rule, pos) in enumerate(derivation.steps(), 1):

            lhs, rhs = derivation.G.P[rule].as_type0()
            rhsn = tuple((X, step, p) for p, X in enumerate(rhs))

            with G.subgraph(graph_attr = {'rank': 'same'}) as S:
                if use_levels: new_level = self.node(S, ('LevelNode', step), gv_args = {'style': 'invis'})
                for node in rhsn: self.node(S, node[0], hash(node), gv_args = {'style': 'rounded, setlinewidth(1.25)' if node in last_sentence else 'rounded, setlinewidth(.25)'})
            if use_levels:
                self.edge(G, prev_level, new_level, gv_args = {'style': 'invis'})
                prev_level = new_level

            if len(lhs) == 1:
                frm = sentence[pos]
                for to in rhsn: self.edge(G, hash(frm), hash(to))
            else:
                id_dot = self.node(G, (step, rule), gv_args = {'shape': 'point', 'width': '.07', 'height': '.07'})
                for frm in sentence[pos:pos + len(lhs)]: self.edge(G, hash(frm), id_dot)
                for to in rhsn: self.edge(G, id_dot, hash(to))

            if len(rhs) > 1:
                with G.subgraph(edge_attr = {'style': 'invis'}, graph_attr = {'rank': 'same'}) as S:
                    for f, t in zip(rhsn, rhsn[1:]): self.edge(S, hash(f), hash(t))

            sentence = remove_ε(sentence[:pos] + rhsn + sentence[pos + len(lhs):])

        self.G = G
        return G
示例#6
0
 def __init__(self, arcs, sep = None):
     self.G = gvDigraph(graph_attr = {'size': '8', 'rankdir': 'LR'})
     for src, dst in arcs: self.G.edge(letstr(src, sep = sep), letstr(dst, sep = sep))