Ejemplo n.º 1
0
    def __init__(self, root=None):
        # 添加一个没有数据的 HEAD
        self._root = root

        # Dot
        self.graph = Dot(rankdir='TB')
        self.graph.set_type('digraph')
        self.graph.set_name('Tree')
    def _create_bpmn_objects(pydot_graph: pydotplus.Dot) -> (list, list):

        bpmn_nodes = []  # list of bpmn nodes
        nodes = {}  # nodes[node_name] = bpmn_node
        for graph_node in pydot_graph.get_node_list():
            name = graph_node.get_name()

            shape = graph_node.__get_attribute__('shape')
            label = graph_node.__get_attribute__('label')
            height = graph_node.__get_attribute__('height')
            width = graph_node.__get_attribute__('width')
            pos = graph_node.__get_attribute__('pos')
            if pos is not None:  # not to include 'system' nodes
                name = modify_str(name)
                label = modify_str(label)
                if name == 'startevent':
                    bpmn_node = StartEvent(pos, height, width)
                elif name == 'endevent':
                    bpmn_node = EndEvent(pos, height, width)
                elif shape == 'diamond':
                    bpmn_node = (ParallelGateway if
                                 (label == '+') else ExclusiveGateway)(pos,
                                                                       height,
                                                                       width)
                elif shape == 'box':
                    bpmn_node = Task(label, pos, height, width)
                else:
                    raise AssertionError(
                        f'type of node {graph_node.get_name()} was not detected!'
                    )

                nodes[name] = bpmn_node
                bpmn_nodes.append(bpmn_node)
        bpmn_edges = []  # list of SequenceFlow() (bpmn edges)
        for graph_edge in pydot_graph.get_edge_list():
            source_name = modify_str(graph_edge.get_source())
            dest_name = modify_str(graph_edge.get_destination())
            source_node = nodes[source_name]
            dest_node = nodes[dest_name]

            pos = graph_edge.__get_attribute__('pos')

            bpmn_edge = SequenceFlow(source_node.get_id(), dest_node.get_id())
            bpmn_edge.set_pos(pos)
            source_node.set_outgoing(bpmn_edge.get_id())
            dest_node.set_incoming(bpmn_edge.get_id())
            bpmn_edges.append(bpmn_edge)

        return bpmn_nodes, bpmn_edges
Ejemplo n.º 3
0
def pydot_graph(layers, node_creator=default_create, **kwargs):
    """Create a :class:`Dot` graph for a list of layers

    Parameters
    ----------
    layers : list of :class:`Layer` instances
        The graph will be created with the layers from that list.
    node_creator : callable (``default_create``)
        A function that creates a :class:`Node` for a given layer.
    kwargs : keyword arguments
        Those will be passed down to ``node_creator`` or :class:`Node`.
    """
    nodes = {}
    edges = []
    for layer in layers:
        nodes[layer] = node_creator(layer, **kwargs)
        if hasattr(layer, 'input_layers'):
            for input_layer in layer.input_layers:
                edges.append((input_layer, layer))
        if hasattr(layer, 'input_layer'):
            edges.append((layer.input_layer, layer))

    graph = Dot('Network', graph_type='digraph')
    for node in nodes.values():
        graph.add_node(node)
    for start, end in edges:
        try:
            graph.add_edge(Edge(nodes[start], nodes[end]))
        except KeyError:
            pass
    return graph
Ejemplo n.º 4
0
def _graph_with_defaults(name: str) -> Dot:
    """Return default pydot graph."""

    result = Dot(graph_name=f'"{name}"')
    result.set_graph_defaults(splines="true",
                              ranksep="0.1 equally",
                              pad="0.1",
                              truecolor="true",
                              bgcolor="#00000000")
    result.set_edge_defaults(fontname="Fira Code",
                             fontcolor="#6f6f6f",
                             color="#6f6f6f",
                             penwidth="2.5")
    result.set_node_defaults(
        fontname="Arimo",
        fontcolor="#ffffff",
        color="#6f6f6f",
        fillcolor="#009641",
        width="1.5",
        style='"rounded,filled"',
        shape="box",
    )
    return result
Ejemplo n.º 5
0
def export(digraph: Subgraph, name: str = "a") -> None:
    """Generate the dependency digraph plot.

    Exports the generated digraph from 'build' to 'name'.png file.

    :param digraph: Dot digraph from 'build'.
    :type digraph: Dot
    :param name: export file's basename.
    :type name: str
    """
    graph = Dot()
    graph.add_subgraph(digraph)
    graph.write(name + ".dot")
    result = graph.create(format="png")
    if result is None:
        print("Error!")
        pass
    else:
        with open(name + ".png", "wb") as file:
            file.write(result)
            pass
        pass
    pass
Ejemplo n.º 6
0
# -*- coding: utf-8 -*-
# coding:utf-8

from pydotplus import Dot, Edge, Node
from PIL import Image
from q41 import make_chunk_list
from q42 import extract_surface

txt_path = '../5/ai.ja.txt.parsed'
sentences = make_chunk_list(txt_path)

sentence_idx = 7
sentence = sentences[sentence_idx]

graph = Dot(graph_type='digraph')
graph.set_fontname('MS Gothic')

# make Node and Edge
for id, chunk in enumerate(sentence):
    word = extract_surface(sentences, sentence_idx, id)
    node = Node(id, label=word)
    graph.add_node(node)
    if chunk.dst != -1:
        edge = Edge(id, chunk.dst)
        graph.add_edge(edge)

graph.write_png('sentence.png')
Image.open('sentence.png')
 def __init__(self, *args, **kwargs):
     self._drawing = Dot(*args, **kwargs)
     self._frames = []
class MyGraph:
    def __init__(self, *args, **kwargs):
        self._drawing = Dot(*args, **kwargs)
        self._frames = []

    def get_node(self, name):
        return self._drawing.get_node(str(name))[0]

    def change_color_node(self, name, color):
        node = self.get_node(name)
        node.obj_dict['attributes']['color'] = color

    def get_edge(self, src, dest):
        return self._drawing.get_edge(src, dest)

    def change_color_edge(self, src, dest, color):
        edge = self.get_edge(src, dest)[0]
        edge.obj_dict['attributes']['color'] = color

    def make_node(self, name):
        return Node(
            name,
            style='filled',
            color='turquoise',
            labelloc='b',
            fontname="Times-Roman:bold",
            fontcolor='black',
            fontsize=50,
        )

    def add_nodes(self, *nodes_names):
        for name in nodes_names:
            node = self.make_node(name)

            self._drawing.add_node(node)

    def link(self, src, dst, w, color=None):
        if color:
            self._drawing.add_edge(
                Edge(src,
                     dst,
                     label=w,
                     fontcolor='blue',
                     color=color,
                     fontsize=50,
                     penwidth=15))
        else:
            self._drawing.add_edge(
                Edge(src,
                     dst,
                     label=w,
                     fontcolor='blue',
                     fontsize=50,
                     penwidth=15))

    def get_image(self):
        img = self._drawing.create_png()
        stream = BytesIO(img)
        img = Image.open(stream)

        return img

    def save_img(self, img_name):
        self._frames.append(self.get_image())
        self._frames[-1].save(
            img_name + '.png',
            format="PNG",
        )
Ejemplo n.º 9
0
 def __init__(self, *args, **kwargs):
     self._drawing = Dot(*args, **kwargs)
     self._adjs = {}
     self._marked = {}
     self._frames = []
Ejemplo n.º 10
0
class MyGraph:
    def __init__(self, *args, **kwargs):
        self._drawing = Dot(*args, **kwargs)
        self._adjs = {}
        self._marked = {}
        self._frames = []

    def add_cluster(self, name, label):
        cluster = Cluster(name)
        cluster.set_label(label)
        self._drawing.add_subgraph(cluster)

    def get_node(self, name):
        return self._drawing.get_node(str(name))[0]

    def make_node(self, name):
        return Node(
            name,
            shape='none',
            style='filled',
            color='azure2',
            image='voter.png',
            labelloc='b',
            fontname="Times-Roman:bold",
            fixedsize='true',
            width=1.0,
            height=1.0,
            fontcolor='white',
            fontsize=15,
        )

    def add_nodes(self, *nodes_names):
        this_path = path.dirname(__file__)
        this_path = path.join(this_path, 'images', 'voter.png')

        self._drawing.shape_files = [this_path]

        for name in nodes_names:
            node = self.make_node(name)

            self._drawing.add_node(node)
            self._adjs[name] = []
            self._marked[name] = False

    def add_nodes_cluster(self, cluster_name, *nodes_names):
        for name in nodes_names:
            node = self.make_node(name)

            cluster = self._drawing.get_subgraph("cluster_" + cluster_name)
            cluster[0].add_node(node)
            if cluster_name is not "unknows":
                self._frames.append(self.get_image())

    def del_node_cluster(self, cluster_name, node):
        cluster = self._drawing.get_subgraph("cluster_" + cluster_name)
        cluster[0].del_node(str(node))
        self._frames.append(self.get_image())

    def link(self, src, dst):
        self._adjs[src].append(dst)
        self._adjs[dst].append(src)

        src = self.get_node(src)
        dst = self.get_node(dst)
        self._drawing.add_edge(Edge(src, dst))

        self._frames.append(self.get_image())

    def mark_node(self, name, color):
        node = self.get_node(name)

        node.set_style('filled')
        node.set_fillcolor(color)

        self._marked[name] = True

        self._frames.append(self.get_image())

    def get_image(self):
        img = self._drawing.create_png()
        stream = BytesIO(img)
        img = Image.open(stream)

        return img

    def is_node_marked(self, name):
        return self._marked[name]

    def bfs(self, name, color, cluster=None):
        to_visit = []
        to_visit.append(name)
        self.mark_node(name, color)

        if cluster is not None:
            self.add_nodes_cluster(cluster, name)
            self.del_node_cluster("unknows", name)

        while to_visit:
            visiting = to_visit.pop(0)

            for v in self._adjs[visiting]:
                if not self.is_node_marked(v):
                    self.mark_node(v, color)
                    to_visit.append(v)

                    if cluster is not None:
                        self.add_nodes_cluster(cluster, v)
                        self.del_node_cluster("unknows", v)

    def count_not_checked_components(self, color):
        count = 0
        for v in self._adjs.keys():
            if not self.is_node_marked(v):
                self.add_cluster(
                    f"unknows_{count+1}",
                    f"Grupo #{count+1} de votos com valor desconhecido")
                self.bfs(v, color, f"unknows_{count+1}")
                count += 1
        return count

    def save_gif(self, file_name):
        self._preprocess_frames()

        self._frames[0].save(file_name + '.gif',
                             format="GIF",
                             append_images=self._frames[1:],
                             save_all=True,
                             duration=len(self._frames) * 10,
                             loop=0)

    def save_img(self, img_name):
        self._frames[-1].save(
            img_name + '.png',
            format="PNG",
        )

    def _preprocess_frames(self):
        biggest_w = max(i.width for i in self._frames)
        biggest_h = max(i.height for i in self._frames)

        for i, old_frame in enumerate(self._frames):
            frame = Image.new('RGBA', (biggest_w, biggest_h),
                              (255, 255, 255, 255))
            frame.paste(old_frame)
            self._frames[i] = frame
        for i in range(5):
            self._frames.append(self._frames[-1])
Ejemplo n.º 11
0
 def get(self) -> Dot:
     """Return pydot graph representation of message."""
     result = Dot(graph_name=self.__message.full_name)
     result.set_graph_defaults(splines="ortho", ranksep="0.8 equally")
     result.set_edge_defaults(fontname="Fira Code",
                              fontcolor="#6f6f6f",
                              color="#6f6f6f")
     result.set_node_defaults(
         fontname="Arimo",
         fontcolor="#ffffff",
         color="#6f6f6f",
         fillcolor="#009641",
         width="1.5",
         style='"rounded,filled"',
         shape="box",
     )
     result.add_node(
         Node(name="Initial",
              fillcolor="#ffffff",
              shape="circle",
              width="0.5",
              label=""))
     for f in self.__message.fields:
         result.add_node(Node(name=f.name))
     for l in self.__message.structure:
         result.add_edge(
             Edge(src=l.source.name,
                  dst=l.target.name,
                  xlabel=self.__edge_label(l)))
     result.add_node(
         Node(name="Final",
              fillcolor="#6f6f6f",
              shape="circle",
              width="0.5",
              label=""))
     return result
Ejemplo n.º 12
0
class MyGraph:
    def __init__(self, *args, **kwargs):
        self._drawing = Dot(*args, **kwargs)
        self._frames = []

    def get_node(self, name):
        return self._drawing.get_node(str(name))[0]

    def make_node(self, name):
        return Node(
            name,
            style='filled',
            color='turquoise',
            labelloc='b',
            fontname="Times-Roman:bold",
            fontcolor='black',
            fontsize=40,
        )

    def add_nodes(self, *nodes_names):
        for name in nodes_names:
            node = self.make_node(name)

            self._drawing.add_node(node)

    def link(self, src, dst, label_edge, w=None):
        if label_edge is "any":
            font_color = "darkgreen"
        elif label_edge is "none":
            font_color = "red"
        else:
            font_color = "indigo"

        if w:
            label_edge = f"{w} ({label_edge})"
            self._drawing.add_edge(
                Edge(src,
                     dst,
                     label=label_edge,
                     fontcolor=font_color,
                     fontsize=40))

        else:
            self._drawing.add_edge(
                Edge(src,
                     dst,
                     label=label_edge,
                     fontcolor=font_color,
                     fontsize=40))

    def get_image(self):
        img = self._drawing.create_png()
        stream = BytesIO(img)
        img = Image.open(stream)

        return img

    def save_img(self, img_name):
        self._frames.append(self.get_image())
        self._frames[-1].save(
            img_name + '.png',
            format="PNG",
        )
Ejemplo n.º 13
0
def dotgraph(graph):
    __graph = Dot(rankdir='TB',
                  fontname="Fangsong",
                  fontcolor='blue',
                  label="有向图的示例")
    __graph.set_type('digraph')
    __graph.set_name('digraph_demo')

    __graph.set_node_defaults(fontname="Fangsong",
                              style='filled',
                              fillcolor='yellow')
    __graph.set_edge_defaults(fontname="Fangsong", color='black')

    for key, value in graph.items():
        # 若节点没有特殊label或者其他属性需求
        # 可以直接以节点名称显示
        # 直接标记方向,不用手动添加
        # node = Node(key)
        # __graph.add_node(node)
        for v in value:
            edge = Edge(key, v)
            __graph.add_edge(edge)

    ret = __graph.write_raw("demo.dot")
    if ret is not True:
        print('生成demo.dot失败')
    ret = __graph.write_svg("demo.svg")
    if ret is not True:
        print('生成graph.svg失败')

    # ret = __graph.write_png("demo.png")
    # if ret is not True:
    #     print('生成graph.png失败')

    return __graph
Ejemplo n.º 14
0
class Tree(object):
    def __init__(self, root=None):
        # 添加一个没有数据的 HEAD
        self._root = root

        # Dot
        self.graph = Dot(rankdir='TB')
        self.graph.set_type('digraph')
        self.graph.set_name('Tree')

    def __str__(self):
        return str(self._root)

    __repr__ = __str__

    def type_check(fun):
        def type_check_wapper(self, *args, **kw):
            if len(args) != 1 or not isinstance(*args, int):
                raise ValueError('类"{}" -> 方法"{}" -> 参数"{}" 无效'.format(
                    self.__class__.__name__, fun.__name__, args))
            fun(self, *args, **kw)

        return type_check_wapper

    @type_check
    def append(self, value):
        node = TreeNode(value)
        # DOT添加新节点
        self.graph.add_node(node.dot_node())

        if self._root is None:
            self._root = node
        else:
            queue = deque()
            queue.append(self._root)

            while queue:
                cur = queue.popleft()
                if cur.left is None:
                    cur.add_left(node)

                    # DOT 添加 edge 左子树
                    self.dot_add_edge_left(cur, node)
                    return
                elif cur.right is None:
                    cur.add_right(node)

                    # dot添加 edge 右子树
                    self.dot_add_edge_right(cur, node)
                    return
                else:
                    # 若左右都不为空,则给判断列表加入子树,继续进行子树判断
                    queue.append(cur.left)
                    queue.append(cur.right)

    """
    # 2019.04.14 23:44:00
    # 之所以屏蔽,这种函数多重包含的原因是
    # 遍历的时候向使用生成器 yield 
    # 但是似乎,函数嵌套了之后,yield会出现和预期不一致的现象?
    # 
    def traversal(self, mode='breadth'):
        if self._root is None:
            print('空树')
        else:
            if mode == 'breadth':
                print('----- 广度优先遍历 -----', end='\n')
                self.__traversal_breadth_first()
            elif mode in ('depth', 'preorder', 'inorder', 'postorder'):
                print('----- 深度优先遍历 -----', end=' ')
                self.__traversal_depth_first(mode)
            else:
                raise ValueError('类"{}" -> 方法"{}" -> 参数"{}" 无效'.format(
                    self.__class__.__name__, self.traversal.__name__, mode))

    def __traversal_depth_first(self, mode='preorder'):
        if mode == 'preorder' or mode == 'depth':
            self.__traversal_preorder(self._root)
        elif mode == 'inorder':
            self.__traversal_inorder()
        elif mode == 'postorder':
            self.__traversal_postorder()
        else:
            raise ValueError('类"{}" -> 方法"{}" -> 参数"{}" 无效'.format(
                self.__class__.__name__, self.__traversal_depth_first.__name__, mode))
        print('')
    """

    def traversal_breadth_first(self):
        """
                广度优先遍历
        """
        queue = deque()
        queue.append(self._root)
        while queue:
            cur = queue.popleft()
            if cur is None:
                continue
            # print(str(cur) + ' -> ', end='')
            yield cur
            queue.append(cur.left)
            queue.append(cur.right)
        # print('')

    # def __traversal_preorder(self, root):
    def traversal_preorder(self):
        """
                深度优先遍历 -> 前序遍历
        """
        # 递归实现
        # if root is None:
        #     return
        # print(root, end=' -> ')
        # self.__traversal_preorder(root.left)
        # self.__traversal_preorder(root.right)

        # 非递归实现
        # print('<前序遍历>')
        queue = deque()
        cur = self._root
        while queue or cur:
            if cur:
                # print(cur, end=' -> ')
                yield cur
                queue.append(cur)
                cur = cur.left
            else:
                cur = queue.pop()
                cur = cur.right

    def traversal_inorder(self):
        """
                深度优先遍历 -> 中序遍历
        """
        # 非递归实现
        # print('<中序遍历>')
        queue = deque()
        cur = self._root
        while queue or cur:
            if cur:
                queue.append(cur)
                cur = cur.left
            else:
                cur = queue.pop()
                # print(cur, end=' -> ')
                yield cur
                cur = cur.right

    def traversal_postorder(self):
        """
                深度优先遍历 -> 后序遍历
        """
        # print('<后序遍历>')
        # """
        #     # 方法一
        #     # 借助的思想:
        #     # 前序遍历:根 -> 左 -> 右
        #     # 后续遍历: 左 -> 右 -> 根 (相当于 前序遍历的先右后左 情况,的逆序)
        #     # 因此:
        #     # 1. 前序遍历,先右后左
        #     # 2. 利用一个新栈,进行逆序
        # """
        # queue_temp = deque()

        # queue = deque()
        # cur = self._root
        # while queue or cur:
        #     if cur:
        #         queue_temp.append(cur)

        #         queue.append(cur)
        #         cur = cur.right
        #     else:
        #         cur = queue.pop()
        #         cur = cur.left

        # for i in range(len(queue_temp)):
        #     print(queue_temp.pop(), end=' -> ')
        """
            # 方法二
            # 借助的思想:
            # 加一个判断量,若当前节点的左右节点都已经被访问过了,那么也需要直接打印
            # 为什么直接cur.right==pre也可以呢? ----- 这种说法错误,若某节点仅存在左子树的时候,就不行了
            # 其实是和我压栈的顺序相关的 
            # 右子树后出,因此上一次弹出的子树为右子树的时候,就可以证明左子树必定访问过了
        """
        queue = deque()
        queue.append(self._root)
        pre = None
        while queue:
            cur = queue[-1]  # 获取栈顶元素
            # if (cur.left is None and cur.right is None) or\
            #         (pre is not None and (cur.right == pre)):     # 此法考虑不够全面
            if (cur.left is None and cur.right is None) or\
                    (pre is not None and (cur.left is pre or cur.right is pre)):

                # print(cur, end=' -> ')
                yield cur
                cur = queue.pop()
                pre = cur
            else:
                if cur.right:
                    queue.append(cur.right)
                if cur.left:
                    queue.append(cur.left)

    def dot_add_edge_left(self, node_src, node_des):
        if not isinstance(node_src, TreeNode) or not isinstance(
                node_src, TreeNode):
            raise ValueError('类"{}" -> 方法"{}" -> 参数"{}"or"{}" 无效'.format(
                self.__class__.__name__, fun.__name__, node_src, node_des))
        edge = Edge(node_src.dot_left(), node_des.dot_value())
        self.graph.add_edge(edge)
        edge = Edge(node_des.dot_parent(), node_src.dot_value(), color='red')
        self.graph.add_edge(edge)

    def dot_add_edge_right(self, node_src, node_des):
        if not isinstance(node_src, TreeNode) or not isinstance(
                node_src, TreeNode):
            raise ValueError('类"{}" -> 方法"{}" -> 参数"{}"or"{}" 无效'.format(
                self.__class__.__name__, fun.__name__, node_src, node_des))
        edge = Edge(node_src.dot_right(), node_des.dot_value())
        self.graph.add_edge(edge)
        edge = Edge(node_des.dot_parent(), node_src.dot_value(), color='red')
        self.graph.add_edge(edge)

    def dot_show(self):
        ret = self.graph.write_raw("demo.dot")
        if ret is not True:
            print('生成demo.dot失败')
        ret = self.graph.write_svg("graph.svg")
        if ret is not True:
            print('生成graph.svg失败')

        os.system("graph.svg")
Ejemplo n.º 15
0
# png和jpg生成的中文是乱码,不知道为啥。svg没有乱码问题
graph.write_png("graph.png")

# 将dot源码写入文件"demo.dot"
ret = graph.write_raw("demo.dot")
print(ret)  #返回True
"""

import pydotplus
import sys
import os
from pydotplus import graph_from_dot_data
from pydotplus import Dot, Node, Edge

graph = Dot(rankdir='TB')
graph.set_type('digraph')
graph.set_name('Dot_Demo')

data = {'start': '开始', '1': '第一步', '2': '第二步', '3': '第三步', 'end': '结束'}

node_name = tuple(data.keys())

graph.set_node_defaults(shape='record')
# 将结点和边关联
i = 0
for key, value in data.items():
    if i == 0 or i == len(data) - 1:
        # node label中{}的作用,相当于开辟新的作用域,且垂直水平方向会相对于当前来进行切换
        """
        digraph G {
Ejemplo n.º 16
0
def write_graph(graph: Dot, filename: Path, fmt: str = "svg") -> None:
    log.info("Creating %s", filename)

    with open(filename, "wb") as f:
        graph.write(f, format=fmt)