Пример #1
0
    def test_layout(self):
        g = networkx.DiGraph()

        g.add_edge('root', 'child 1')
        g.add_edge('child 1', 'grandchild 1')
        g.add_edge('child 1', 'grandchild 2')
        g.add_edge('root', 'child 2')
        g.add_edge('child 2', 'grandchild 3')
        g.add_edge('child 2', 'grandchild 4')
        g.add_edge('child 2', 'grandchild 5')

        layout = tree_layout(g)

        expected_root_x, expected_root_y = (0.5, 1.0)
        self.assertAlmostEqual(layout['root'][0], expected_root_x)
        self.assertAlmostEqual(layout['root'][1], expected_root_y)

        gc_xs = [value[0] for key, value in layout.items()
                 if key.startswith('child')]
        expected_gc_xs = [x / 3.0 for x in range(1, 3)]
        nptest.assert_almost_equal(sorted(gc_xs), expected_gc_xs)
        gc_ys = [value[1] for key, value in layout.items()
                 if key.startswith('child')]
        expected_gc_ys = [0.5] * 2
        nptest.assert_almost_equal(sorted(gc_ys), expected_gc_ys)

        gc_xs = [value[0] for key, value in layout.items()
                 if 'grandchild' in key]
        expected_gc_xs = [x / 6.0 for x in range(1, 6)]
        nptest.assert_almost_equal(sorted(gc_xs), expected_gc_xs)
        gc_ys = [value[1] for key, value in layout.items()
                 if 'grandchild' in key]
        expected_gc_ys = [0.0] * 5
        nptest.assert_almost_equal(sorted(gc_ys), expected_gc_ys)
Пример #2
0
    def test_layout(self):
        g = networkx.DiGraph()

        g.add_edge('root', 'child 1')
        g.add_edge('child 1', 'grandchild 1')
        g.add_edge('child 1', 'grandchild 2')
        g.add_edge('root', 'child 2')
        g.add_edge('child 2', 'grandchild 3')
        g.add_edge('child 2', 'grandchild 4')
        g.add_edge('child 2', 'grandchild 5')

        layout = tree_layout(g)
        self.assert_layout_positions(layout['root'], (0.5, 1.0))
        self.assert_layout_positions(layout['child 1'], (2 / 3., 0.5))
        self.assert_layout_positions(layout['child 2'], (1 / 3., 0.5))
        self.assert_layout_positions(layout['grandchild 1'], (5 / 6., 0.0))
        self.assert_layout_positions(layout['grandchild 2'], (4 / 6., 0.0))
        self.assert_layout_positions(layout['grandchild 3'], (3 / 6., 0.0))
        self.assert_layout_positions(layout['grandchild 4'], (2 / 6., 0.0))
        self.assert_layout_positions(layout['grandchild 5'], (1 / 6., 0.0))
Пример #3
0
    def test_layout(self):
        g = networkx.DiGraph()

        g.add_edge('root', 'child 1')
        g.add_edge('child 1', 'grandchild 1')
        g.add_edge('child 1', 'grandchild 2')
        g.add_edge('root', 'child 2')
        g.add_edge('child 2', 'grandchild 3')
        g.add_edge('child 2', 'grandchild 4')
        g.add_edge('child 2', 'grandchild 5')

        layout = tree_layout(g)
        self.assert_layout_positions(layout['root'], (0.5, 1.0))
        self.assert_layout_positions(layout['child 1'], (2 / 3., 0.5))
        self.assert_layout_positions(layout['child 2'], (1 / 3., 0.5))
        self.assert_layout_positions(layout['grandchild 1'], (5 / 6., 0.0))
        self.assert_layout_positions(layout['grandchild 2'], (4 / 6., 0.0))
        self.assert_layout_positions(layout['grandchild 3'], (3 / 6., 0.0))
        self.assert_layout_positions(layout['grandchild 4'], (2 / 6., 0.0))
        self.assert_layout_positions(layout['grandchild 5'], (1 / 6., 0.0))
Пример #4
0
    def test_layout(self):
        g = networkx.DiGraph()

        g.add_edge('root', 'child 1')
        g.add_edge('child 1', 'grandchild 1')
        g.add_edge('child 1', 'grandchild 2')
        g.add_edge('root', 'child 2')
        g.add_edge('child 2', 'grandchild 3')
        g.add_edge('child 2', 'grandchild 4')
        g.add_edge('child 2', 'grandchild 5')

        layout = tree_layout(g)

        expected_root_x, expected_root_y = (0.5, 1.0)
        self.assertAlmostEqual(layout['root'][0], expected_root_x)
        self.assertAlmostEqual(layout['root'][1], expected_root_y)

        gc_xs = [
            value[0] for key, value in layout.items()
            if key.startswith('child')
        ]
        expected_gc_xs = [x / 3.0 for x in range(1, 3)]
        nptest.assert_almost_equal(sorted(gc_xs), expected_gc_xs)
        gc_ys = [
            value[1] for key, value in layout.items()
            if key.startswith('child')
        ]
        expected_gc_ys = [0.5] * 2
        nptest.assert_almost_equal(sorted(gc_ys), expected_gc_ys)

        gc_xs = [
            value[0] for key, value in layout.items() if 'grandchild' in key
        ]
        expected_gc_xs = [x / 6.0 for x in range(1, 6)]
        nptest.assert_almost_equal(sorted(gc_xs), expected_gc_xs)
        gc_ys = [
            value[1] for key, value in layout.items() if 'grandchild' in key
        ]
        expected_gc_ys = [0.0] * 5
        nptest.assert_almost_equal(sorted(gc_ys), expected_gc_ys)
Пример #5
0
    def do_layout(self, size=None, force=False):
        """ Nodes of the graph will be layed out based on the the style
            attribute
        """

        if not self._graph_layout_needed or len(self.components) == 0:
            return

        def _apply_graphviz_layout(layout):
            min_x = min([pos[0] for pos in layout.values()])
            max_y = max([pos[1] for pos in layout.values()])

            for component in self.components:
                component.x = self.width + layout[component._key][0] - min_x
                component.y = self.height + layout[component._key][1] - max_y

        initial_positions = {
            node.value: node.position for node in self.components
        }
        if all(point == [0.0, 0.0] for point in initial_positions.values()):
            initial_positions = None

        scale = min(self.bounds)

        if self.style == 'tree':
            try:
                layout = networkx.drawing.nx_agraph.pygraphviz_layout(
                    self.graph, prog='dot'
                )
                _apply_graphviz_layout(layout)
            except ImportError:
                layout = tree_layout(self.graph)

                # resize the bounds to fit the graph
                depths = [v[1] for v in layout.values()]
                widths = [depths.count(d) for d in numpy.unique(depths)]
                max_width = max(widths)
                max_depth = len(widths)

                self.bounds = [max(75, self.components[0].width)*max_width,
                               max(50, self.components[0].height)*max_depth]

                for component in self.components:
                    component.x = self.width * layout[component._key][0]
                    component.y = self.height * layout[component._key][1]

        elif self.style == 'shell':
            layout = networkx.shell_layout(self.graph)

            # resize the bounds to fit the graph
            radius = numpy.log2(len(layout))
            self.bounds = [max(75, self.components[0].width)*2*radius,
                           max(50, self.components[0].height)*2*radius]

            for component in self.components:
                component.y = self.height * (1 + layout[component._key][0])/2
                component.x = self.width * (1 + layout[component._key][1])/2

        elif self.style == 'spectral':
            layout = networkx.spectral_layout(self.graph)

            # resize the bounds to fit the graph
            radius = numpy.log2(len(layout))
            self.bounds = [max(75, self.components[0].width)*2*radius,
                           max(50, self.components[0].height)*2*radius]

            for component in self.components:
                component.y = self.height * (1 + layout[component._key][0])/2
                component.x = self.width * (1 + layout[component._key][1])/2

        elif self.style == 'circular':
            try:
                layout = networkx.drawing.nx_agraph.pygraphviz_layout(
                    self.graph, prog='twopi'
                )
                _apply_graphviz_layout(layout)
            except ImportError:
                layout = networkx.circular_layout(
                    self.graph,
                    scale=min(self.bounds) // 2,
                    center=[bound // 2 for bound in self.bounds],
                )

            for component in self.components:
                component.x = layout[component._key][0]
                component.y = layout[component._key][1]

        else:
            layout = networkx.spring_layout(
                self.graph,
                pos=initial_positions,
                scale=scale,
            )

            # resize the bounds to fit the graph
            radius = len(layout)
            self.bounds = [max(75, self.components[0].width)*2*radius,
                           max(50, self.components[0].height)*2*radius]

            for component in self.components:
                component.x = layout[component._key][0]
                component.y = layout[component._key][1]

        self._graph_layout_needed = False
Пример #6
0
 def test_not_acyclic(self):
     g = networkx.DiGraph()
     g.add_edge('root', 'child')
     g.add_edge('child', 'root')
     with self.assertRaisesRegexp(ValueError, 'must not contain cycles'):
         tree_layout(g)
Пример #7
0
 def test_not_directed(self):
     g = networkx.Graph()
     with self.assertRaisesRegexp(ValueError, 'directed'):
         tree_layout(g)
Пример #8
0
 def test_non_2D(self):
     g = networkx.DiGraph()
     with self.assertRaisesRegexp(ValueError, 'only 2D graphs'):
         tree_layout(g, dim=1)
         tree_layout(g, dim=3)
Пример #9
0
    def do_layout(self, size=None, force=False):
        """ Nodes of the graph will be layed out based on the the style
            attribute
        """

        if not self._graph_layout_needed or len(self.components) == 0:
            return

        def _apply_graphviz_layout(layout):
            min_x = min([pos[0] for pos in layout.values()])
            max_y = max([pos[1] for pos in layout.values()])

            for component in self.components:
                component.x = self.width + layout[component._key][0] - min_x
                component.y = self.height + layout[component._key][1] - max_y

        initial_positions = {
            node.value: node.position for node in self.components
        }
        if all(point == [0.0, 0.0] for point in initial_positions.values()):
            initial_positions = None

        scale = min(self.bounds)

        if self.style == 'tree':
            try:
                layout = networkx.drawing.nx_agraph.pygraphviz_layout(
                    self.graph, prog='dot'
                )
                _apply_graphviz_layout(layout)
            except ImportError:
                layout = tree_layout(self.graph)

                # resize the bounds to fit the graph
                depths = [v[1] for v in layout.values()]
                widths = [depths.count(d) for d in numpy.unique(depths)]
                max_width = max(widths)
                max_depth = len(widths)

                self.bounds = [max(75, self.components[0].width)*max_width,
                               max(50, self.components[0].height)*max_depth]

                for component in self.components:
                    component.x = self.width * layout[component._key][0]
                    component.y = self.height * layout[component._key][1]

        elif self.style == 'shell':
            layout = networkx.shell_layout(self.graph)

            # resize the bounds to fit the graph
            radius = numpy.log2(len(layout))
            self.bounds = [max(75, self.components[0].width)*2*radius,
                           max(50, self.components[0].height)*2*radius]

            for component in self.components:
                component.y = self.height * (1 + layout[component._key][0])/2
                component.x = self.width * (1 + layout[component._key][1])/2

        elif self.style == 'spectral':
            layout = networkx.spectral_layout(self.graph)

            # resize the bounds to fit the graph
            radius = numpy.log2(len(layout))
            self.bounds = [max(75, self.components[0].width)*2*radius,
                           max(50, self.components[0].height)*2*radius]

            for component in self.components:
                component.y = self.height * (1 + layout[component._key][0])/2
                component.x = self.width * (1 + layout[component._key][1])/2

        elif self.style == 'circular':
            try:
                layout = networkx.drawing.nx_agraph.pygraphviz_layout(
                    self.graph, prog='twopi'
                )
                _apply_graphviz_layout(layout)
            except ImportError:
                layout = networkx.circular_layout(
                    self.graph,
                    scale=min(self.bounds) // 2,
                    center=[bound // 2 for bound in self.bounds],
                )

            for component in self.components:
                component.x = layout[component._key][0]
                component.y = layout[component._key][1]

        else:
            layout = networkx.spring_layout(
                self.graph,
                pos=initial_positions,
                scale=scale,
            )

            # resize the bounds to fit the graph
            radius = len(layout)
            self.bounds = [max(75, self.components[0].width)*2*radius,
                           max(50, self.components[0].height)*2*radius]

            for component in self.components:
                component.x = layout[component._key][0]
                component.y = layout[component._key][1]

        self._graph_layout_needed = False
Пример #10
0
 def test_not_acyclic(self):
     g = networkx.DiGraph()
     g.add_edge('root', 'child')
     g.add_edge('child', 'root')
     with self.assertRaisesRegexp(ValueError, 'must not contain cycles'):
         tree_layout(g)
Пример #11
0
 def test_not_directed(self):
     g = networkx.Graph()
     with self.assertRaisesRegexp(ValueError, 'directed'):
         tree_layout(g)
Пример #12
0
 def test_non_2D(self):
     g = networkx.DiGraph()
     with self.assertRaisesRegexp(ValueError, 'only 2D graphs'):
         tree_layout(g, dim=1)
         tree_layout(g, dim=3)