예제 #1
0
 def unwind_refs(graph, field="label"):
     unwind = {}
     _, levels = get_graph_levels(graph)
     for l in sorted(levels.keys()):
         for n_id in levels[l]:
             new = re.sub(r'@@(\d+)@@', lambda x: f"{unwind[int(x.group(1))]}", graph.nodes[n_id][field])
             unwind[n_id] = new
     return unwind
예제 #2
0
    def reorder(graph: nx.DiGraph):
        try:
            _, levels = get_graph_levels(graph)
        except Exception as ex:
            _logger.warning("skip - Failed to invoke reorder()")
            return

        # order by levels
        relabel_map = {}
        next_node_id = 1
        for level in sorted(levels.keys()):
            nodes_by_label = {}
            for n_id in levels[level]:
                # for consistency
                n = graph.nodes[n_id]
                n["label"] = re.sub(
                    r"@@(\d+)@@",
                    lambda x: f"@@{relabel_map[int(x.group(1))]}@@",
                    n["label"])
                if n["label"] not in nodes_by_label:
                    nodes_by_label[n["label"]] = n_id
                else:
                    # duplicate label
                    # safe merge since previous levels are fixed
                    exists_node_id = nodes_by_label[n["label"]]
                    # successors - should be the same due to label
                    predecessors = graph.predecessors(n_id)
                    for p_id in predecessors:
                        graph.add_edge(p_id, exists_node_id)
                        graph.nodes[p_id]["label"] = re.sub(
                            f"@@{n_id}@@", lambda x: f"@@{exists_node_id}@@",
                            graph.nodes[p_id]["label"])
                    graph.remove_node(n_id)
            nodes_order = sorted(nodes_by_label.keys())
            for label in nodes_order:
                n_id = nodes_by_label[label]
                relabel_map[n_id] = next_node_id
                next_node_id += 1

        # update labels
        # double mapping since new and old labels are overlap
        nx.relabel.relabel_nodes(graph,
                                 {k: str(v)
                                  for k, v in relabel_map.items()},
                                 copy=False)
        nx.relabel.relabel_nodes(graph,
                                 {str(v): v
                                  for v in relabel_map.values()},
                                 copy=False)
예제 #3
0
def draw_decomposition_graph(graph, title=None, pos=None):
    options = {
        'node_color': 'lightblue',
        'node_size': 400,
        'width': 1,
        'arrowstyle': '-|>',
        'arrowsize': 14,
    }

    if not pos:
        try:
            _, levels = get_graph_levels(graph)

            pos = {}
            max_num_nodes_per_layer = max([len(levels[l]) for l in levels]) + 1
            for l in levels.keys():
                num_layer_nodes = len(levels[l])
                if num_layer_nodes == 0: continue
                space_factor = max_num_nodes_per_layer // (num_layer_nodes + 1)
                for i, n_id in enumerate(sorted(levels[l])):
                    pos[n_id] = ((i + 1) * space_factor, l)
        except:  # cyclic
            print("a cyclic graph - change layout (no-layers)")
            pos = nx.spring_layout(graph, k=0.5)
    nx.draw_networkx(graph, pos=pos, arrows=True, with_labels=True, **options)
    for node in graph.nodes:
        plt.text(pos[node][0], pos[node][1] - 0.1,
                 s=re.sub(r'@@(\d+)@@', r'#\g<1>', graph.nodes[node]['label']),
                 bbox=dict(facecolor='red', alpha=0.5),
                 horizontalalignment='center',
                 wrap=True, size=6)

    if title:
        plt.title(title)

    plt.axis("off")
    plt.show()
    plt.clf()