def test_invalid_half_edge():
    with pytest.raises(nx.NetworkXException):
        embedding_data = {
            1: [2, 3, 4],
            2: [1, 3, 4],
            3: [1, 2, 4],
            4: [1, 2, 3]
        }
        embedding = nx.PlanarEmbedding()
        embedding.set_data(embedding_data)
        nx.combinatorial_embedding_to_pos(embedding)
예제 #2
0
def check_embedding_data(embedding_data):
    """Checks that the planar embedding of the input is correct"""
    embedding = nx.PlanarEmbedding()
    embedding.set_data(embedding_data)
    pos_fully = nx.combinatorial_embedding_to_pos(embedding, False)
    msg = "Planar drawing does not conform to the embedding (fully " "triangulation)"
    assert planar_drawing_conforms_to_embedding(embedding, pos_fully), msg
    check_edge_intersections(embedding, pos_fully)
    pos_internally = nx.combinatorial_embedding_to_pos(embedding, True)
    msg = "Planar drawing does not conform to the embedding (internal " "triangulation)"
    assert planar_drawing_conforms_to_embedding(embedding, pos_internally), msg
    check_edge_intersections(embedding, pos_internally)
예제 #3
0
    def __init__(self, G: Graph, pos: POSITIONS = None):

        if nx.number_of_selfloops(G) != 0:
            raise OrthogonalException(
                'There can be no self loops in the graph')

        if nx.is_connected(G) is False:
            raise OrthogonalException(
                'The graph or parts of it are not connected.')

        self.logger: Logger = getLogger(__name__)
        if pos is None:
            is_planar, self.embedding = nx.check_planarity(G)
            assert is_planar
            pos = nx.combinatorial_embedding_to_pos(self.embedding)
        else:
            if self.numberOfCrossings(G, pos) != 0:
                raise OrthogonalException(
                    'The graph has edges that cross each other')
            self.embedding: nx.PlanarEmbedding = self.convert_pos_to_embedding(
                G, pos)

        self.G: Graph = G.copy()
        self.pos = pos  # is only used to find the ext_face now.
        self.dcel: Dcel = Dcel(G, self.embedding)
        self.ext_face = self.get_external_face()
def main():
    # Cycle graph

    _, embedding = nx.check_planarity(nx.cycle_graph(20))
    embedding_fully, _ = nx.triangulate_embedding(embedding, True)
    diff_fully = nx.Graph(list(embedding_fully.edges - embedding.edges))
    embedding_internal, _ = nx.triangulate_embedding(embedding, False)
    diff_internal = nx.Graph(list(embedding_internal.edges - embedding.edges))
    pos = nx.combinatorial_embedding_to_pos(embedding_fully)
    nx.draw(diff_fully, pos, alpha=0.5, width=1, style="dotted", node_size=30)
    nx.draw(embedding, pos, width=2 , node_size=30)
    plt.savefig("drawing_cycle_fully_triangulated.png", format="PNG")
    plt.show()

    pos = nx.combinatorial_embedding_to_pos(embedding_internal)
    nx.draw(diff_internal, pos, alpha=0.5, width=1, style="dotted", node_size=30)
    nx.draw(embedding, pos, width=2, node_size=30)
    plt.savefig("drawing_cycle_internally_triangulated.png", format="PNG")
    plt.show()

    # Other graph
    G = nx.Graph([(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (1, 4), (4, 3)])
    is_planar, embedding = nx.check_planarity(G)
    print(is_planar)
    embedding_fully, _ = nx.triangulate_embedding(embedding, True)
    diff_fully = nx.Graph(list(embedding_fully.edges - embedding.edges))
    embedding_internal, _ = nx.triangulate_embedding(embedding, False)
    diff_internal = nx.Graph(list(embedding_internal.edges - embedding.edges))
    pos = nx.combinatorial_embedding_to_pos(embedding_fully)
    nx.draw(diff_fully, pos, alpha=0.5, width=1, style="dotted", node_size=30)
    nx.draw(embedding, pos, width=2, node_size=30)
    plt.savefig("drawing_other_fully_triangulated.png", format="PNG")
    plt.show()

    pos = nx.combinatorial_embedding_to_pos(embedding_internal)
    nx.draw(diff_internal, pos, alpha=0.5, width=1, style="dotted", node_size=30)
    nx.draw(embedding, pos, width=2, node_size=30)
    plt.savefig("drawing_other_internally_triangulated.png", format="PNG")
    plt.show()

    embedding_data = {0: [36, 42], 1: [], 2: [23, 16], 3: [19], 4: [23, 17], 5: [45, 18], 6: [42, 29, 40], 7: [48, 26, 32], 8: [15, 44, 23], 9: [11, 27], 10: [39, 11, 32, 47, 26, 15], 11: [10, 9], 12: [41, 34, 35], 13: [48], 14: [28, 45], 15: [34, 8, 10], 16: [2, 39, 21], 17: [4], 18: [5], 19: [22, 3], 20: [], 21: [16, 49], 22: [26, 47, 19], 23: [8, 2, 4], 24: [46], 25: [], 26: [7, 34, 10, 22, 38], 27: [9, 48], 28: [36, 41, 14], 29: [6], 30: [48], 31: [], 32: [7, 10, 46], 33: [48], 34: [12, 15, 26], 35: [12, 41], 36: [0, 28, 43], 37: [47], 38: [26], 39: [16, 10], 40: [6], 41: [28, 12, 35], 42: [44, 0, 6], 43: [36], 44: [8, 42], 45: [14, 5], 46: [32, 24], 47: [22, 10, 37], 48: [27, 7, 13, 30, 33], 49: [21]}
    embedding = nx.PlanarEmbedding()
    embedding.set_data(embedding_data)
    pos = nx.combinatorial_embedding_to_pos(embedding, fully_triangulate=False)
    nx.draw(embedding, pos, node_size=30)
    plt.savefig("drawing_large_graph_internally_triangulated.png", format="PNG")
    plt.show()
예제 #5
0
def check_embedding_data(embedding_data):
    """Checks that the planar embedding of the input is correct"""
    embedding = nx.PlanarEmbedding()
    embedding.set_data(embedding_data)
    pos_fully = nx.combinatorial_embedding_to_pos(embedding, False)
    msg = "Planar drawing does not conform to the embedding (fully " \
          "triangulation)"
    assert_true(planar_drawing_conforms_to_embedding(embedding, pos_fully),
                msg)
    check_edge_intersections(embedding, pos_fully)
    pos_internally = nx.combinatorial_embedding_to_pos(embedding, True)
    msg = "Planar drawing does not conform to the embedding (internal " \
          "triangulation)"
    assert_true(planar_drawing_conforms_to_embedding(embedding,
                                                     pos_internally),
                msg)
    check_edge_intersections(embedding, pos_internally)
예제 #6
0
def planar_layout(G, scale=1, center=None, dim=2):
    """Position nodes without edge intersections.

    Parameters
    ----------
    G : NetworkX graph or list of nodes
        A position will be assigned to every node in G. If G is of type
        nx.PlanarEmbedding, the positions are selected accordingly.

    scale : number (default: 1)
        Scale factor for positions.

    center : array-like or None
        Coordinate pair around which to center the layout.

    dim : int
        Dimension of layout.

    Returns
    -------
    pos : dict
        A dictionary of positions keyed by node

    Raises
    ------
    NetworkXException
        If G is not planar

    Examples
    --------
    >>> G = nx.path_graph(4)
    >>> pos = nx.planar_layout(G)
    """
    import numpy as np

    if dim != 2:
        raise ValueError("can only handle 2 dimensions")

    G, center = _process_params(G, center, dim)

    if len(G) == 0:
        return {}

    if isinstance(G, nx.PlanarEmbedding):
        embedding = G
    else:
        is_planar, embedding = nx.check_planarity(G)
        if not is_planar:
            raise nx.NetworkXException("G is not planar.")
    pos = nx.combinatorial_embedding_to_pos(embedding)
    node_list = list(embedding)
    pos = np.row_stack([pos[x] for x in node_list])
    pos = pos.astype(np.float64)
    pos = rescale_layout(pos, scale=scale) + center
    return dict(zip(node_list, pos))
예제 #7
0
    def __init__(self, G, pos=None):
        if pos is None:
            is_planar, embedding = nx.check_planarity(G)
            pos = nx.combinatorial_embedding_to_pos(embedding)
        else:
            embedding = convert_pos_to_embedding(G, pos)

        self.G = G.copy()
        self.dcel = Dcel(G, embedding)
        self.dcel.ext_face = self.get_external_face(pos)
        self.dcel.ext_face.is_external = True
    def __init__(self, G, pos=None):
        assert nx.number_of_selfloops(G) == 0
        assert nx.is_connected(G)
        if pos is None:
            is_planar, self.embedding = nx.check_planarity(G)
            assert is_planar
            pos = nx.combinatorial_embedding_to_pos(self.embedding)
        else:
            assert number_of_cross(G, pos) == 0
            self.embedding = convert_pos_to_embdeding(G, pos)

        self.G = G.copy()
        self.pos = pos # is only used to find the ext_face now.
        self.dcel = DCEL.Dcel(G, self.embedding)
        self.ext_face = self.get_external_face()
def test_random():
    while True:
        n = 50
        p = 1.0
        is_planar = False
        while not is_planar:
            G = nx.fast_gnp_random_graph(n, p)
            is_planar, embedding = nx.check_planarity(G)
            p *= 0.9
        pos = nx.combinatorial_embedding_to_pos(embedding,
                                                fully_triangulate=False)
        assert_true(planar_drawing_conforms_to_embedding(embedding, pos),
                    "Planar drawing does not conform to the embedding")
        assert_true(is_planar_drawing_correct(G, pos),
                    "Planar drawing is not correct")
        print("Graph correct")
def main():
    while True:
        n = 50
        p = 1.0
        is_planar = False
        while not is_planar:
            G = nx.fast_gnp_random_graph(n, p)
            is_planar, embedding = nx.check_planarity(G)
            p *= 0.99
        print("Embedding: ", embedding.get_data())
        print("Displaying not fully triangulated drawing")
        plt.subplot(1, 2, 1)
        nx.draw_planar(embedding, node_size=2)

        pos = nx.combinatorial_embedding_to_pos(embedding, fully_triangulate=True)
        print("Displaying fully triangulated drawing")
        plt.subplot(1, 2, 2)
        nx.draw(G, pos, node_size=2)

        plt.show()
예제 #11
0
    def plot(self, **kwargs):
        """Plots the graph.

        Parameters
        ----------
        G: networkx.Graph


        """
        G = None
        with_labels = False
        use_planar_drawer = False
        node_size = 100
        if 'G' in kwargs:
            G = kwargs['G']
        if 'with_labels' in kwargs:
            with_labels = kwargs['with_labels']
        if 'use_planar_drawer' in kwargs:
            use_planar_drawer = kwargs['use_planar_drawer']
        if 'node_size' in kwargs:
            node_size = kwargs['node_size']

        if G is None:
            G = self.to_networkx_graph()
        # Generate planar embedding or use default algorithm.
        pos = None
        if use_planar_drawer:
            emb = self.to_planar_embedding()
            pos = nx.combinatorial_embedding_to_pos(emb,
                                                    fully_triangulate=False)
        # Take color attributes on the nodes into account.
        colors = nx.get_node_attributes(G, 'color').values()
        if len(colors) == G.number_of_nodes():
            nx.draw(G,
                    pos=pos,
                    with_labels=with_labels,
                    node_color=list(colors),
                    node_size=node_size)
        else:
            nx.draw(G, pos=pos, with_labels=with_labels, node_size=node_size)
예제 #12
0
def test_invalid_half_edge():
    embedding_data = {1: [2, 3], 2: [1, 3], 3: [1, 2], 4: [1, 2, 3]}
    embedding = nx.PlanarEmbedding()
    embedding.set_data(embedding_data)
    nx.combinatorial_embedding_to_pos(embedding)
예제 #13
0
def test_invalid_half_edge():
    embedding_data = {1: [2, 3, 4], 2: [1, 3, 4], 3: [1, 2, 4], 4: [1, 2, 3]}
    embedding = nx.PlanarEmbedding()
    embedding.set_data(embedding_data)
    nx.combinatorial_embedding_to_pos(embedding)
예제 #14
0
def convert_to_game_structure(graph: nx.Graph, embedding: nx.PlanarEmbedding,
                              path_grouping):
    positions = scale_positions(
        nx.combinatorial_embedding_to_pos(embedding, True))
    points = [GraphicsPoint] * len(graph.nodes)
    paths = []

    # Initialize points
    for index, position in positions.items():
        point = GraphicsPoint(*position, False)
        point.index = index
        points[index] = point

    # Initialize paths
    for path_start, path_end, mid_point in path_grouping:
        start_point = points[path_start[0]]
        end_point = points[path_end[1]]

        # The path was created from the same point to itself
        if start_point == end_point:
            end_point = points[path_start[1]]

            # Make small difference to width of the paths
            delta_pos = end_point - start_point
            mid_point = start_point + delta_pos.scalar(0.5)
            shift = delta_pos.rotate_anticlock().normalized().scalar(5)

            pos_control = mid_point + shift
            neg_control = mid_point - shift

            path_0 = Path([
                GraphicsBezier(start_point, end_point, gc.LINE_COLOR,
                               pos_control, pos_control)
            ], start_point, end_point)
            path_1 = Path([
                GraphicsBezier(start_point, end_point, gc.LINE_COLOR,
                               neg_control, neg_control)
            ], start_point, end_point)

            # Update paths of points
            start_point.add_to_path(path_0)
            start_point.add_to_path(path_1)
            end_point.add_to_path(path_0)
            end_point.add_to_path(path_1)

            paths.append((path_0, path_1, points[path_start[1]]))
        # Normal path
        else:
            middle_point = points[path_start[1]]

            path_0 = Path([GraphicsBezier(start_point, middle_point)],
                          start_point, middle_point)
            path_1 = Path([GraphicsBezier(middle_point, end_point)],
                          middle_point, end_point)

            # Update paths of points
            start_point.add_to_path(path_0)
            middle_point.add_to_path(path_0)
            middle_point.add_to_path(path_1)
            end_point.add_to_path(path_1)

            paths.append((path_0, path_1, middle_point))

        # Test whether the points are still valid
        valid_point(start_point, start_point, end_point)
        valid_point(end_point, start_point, end_point)
    return points, paths