Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Tiago Peixoto
graph-tool
Commits
ae9857c0
Commit
ae9857c0
authored
Oct 18, 2013
by
Tiago Peixoto
Browse files
Implement radial_tree_layout()
parent
30dee452
Changes
5
Hide whitespace changes
Inline
Side-by-side
doc/draw.rst
View file @
ae9857c0
...
...
@@ -6,6 +6,7 @@
.. autofunction:: sfdp_layout
.. autofunction:: fruchterman_reingold_layout
.. autofunction:: arf_layout
.. autofunction:: radial_tree_layout
.. autofunction:: random_layout
...
...
src/graph/layout/Makefile.am
View file @
ae9857c0
...
...
@@ -18,6 +18,7 @@ libgraph_tool_layout_la_SOURCES = \
graph_arf.cc
\
graph_fruchterman_reingold.cc
\
graph_sfdp.cc
\
graph_radial.cc
\
graph_bind_layout.cc
libgraph_tool_layout_la_include_HEADERS
=
\
...
...
src/graph/layout/graph_bind_layout.cc
View file @
ae9857c0
...
...
@@ -21,10 +21,12 @@ using namespace boost::python;
void
export_arf
();
void
export_fruchterman_reingold
();
void
export_sfdp
();
void
export_radial
();
BOOST_PYTHON_MODULE
(
libgraph_tool_layout
)
{
export_arf
();
export_fruchterman_reingold
();
export_sfdp
();
export_radial
();
}
src/graph/layout/graph_radial.cc
0 → 100644
View file @
ae9857c0
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2013 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include
"graph.hh"
#include
"graph_filtering.hh"
#include
"graph_selectors.hh"
#include
"graph_properties.hh"
#include
<cmath>
using
namespace
std
;
using
namespace
boost
;
using
namespace
graph_tool
;
struct
do_get_radial
{
template
<
class
Graph
,
class
PosProp
,
class
LevelMap
>
void
operator
()(
Graph
&
g
,
PosProp
tpos
,
LevelMap
level
,
size_t
root
,
bool
weighted
,
double
r
)
const
{
typedef
typename
graph_traits
<
Graph
>::
vertex_descriptor
vertex_t
;
typedef
property_map_type
::
apply
<
int
,
GraphInterface
::
vertex_index_map_t
>::
type
vcount_t
;
vcount_t
::
unchecked_t
count
(
get
(
vertex_index
,
g
),
num_vertices
(
g
));
if
(
!
weighted
)
{
typename
graph_traits
<
Graph
>::
vertex_iterator
v
,
v_end
;
for
(
tie
(
v
,
v_end
)
=
vertices
(
g
);
v
!=
v_end
;
++
v
)
count
[
*
v
]
=
1
;
}
else
{
deque
<
vertex_t
>
q
;
typename
graph_traits
<
Graph
>::
vertex_iterator
v
,
v_end
;
for
(
tie
(
v
,
v_end
)
=
vertices
(
g
);
v
!=
v_end
;
++
v
)
if
(
out_degree
(
*
v
,
g
)
==
0
)
{
q
.
push_back
(
*
v
);
count
[
*
v
]
=
1
;
}
typedef
property_map_type
::
apply
<
uint8_t
,
GraphInterface
::
vertex_index_map_t
>::
type
vmark_t
;
vmark_t
::
unchecked_t
mark
(
get
(
vertex_index
,
g
),
num_vertices
(
g
));
while
(
!
q
.
empty
())
{
vertex_t
v
=
q
.
front
();
q
.
pop_front
();
typename
graph_traits
<
Graph
>::
in_edge_iterator
e
,
e_end
;
for
(
tie
(
e
,
e_end
)
=
in_edges
(
v
,
g
);
e
!=
e_end
;
++
e
)
{
vertex_t
w
=
source
(
*
e
,
g
);
count
[
w
]
+=
count
[
v
];
if
(
!
mark
[
w
])
{
q
.
push_back
(
w
);
mark
[
w
]
=
true
;
}
}
}
}
vector
<
vector
<
vertex_t
>
>
layers
(
1
);
layers
[
0
].
push_back
(
root
);
bool
last
=
false
;
while
(
!
last
)
{
layers
.
resize
(
layers
.
size
()
+
1
);
vector
<
vertex_t
>&
new_layer
=
layers
[
layers
.
size
()
-
1
];
vector
<
vertex_t
>&
last_layer
=
layers
[
layers
.
size
()
-
2
];
last
=
true
;
for
(
size_t
i
=
0
;
i
<
last_layer
.
size
();
++
i
)
{
vertex_t
v
=
last_layer
[
i
];
typename
graph_traits
<
Graph
>::
out_edge_iterator
e
,
e_end
;
for
(
tie
(
e
,
e_end
)
=
out_edges
(
v
,
g
);
e
!=
e_end
;
++
e
)
{
vertex_t
w
=
target
(
*
e
,
g
);
new_layer
.
push_back
(
w
);
if
(
layers
.
size
()
-
1
==
level
[
w
])
last
=
false
;
}
if
(
out_degree
(
v
,
g
)
==
0
)
new_layer
.
push_back
(
v
);
}
if
(
last
)
layers
.
pop_back
();
}
typedef
property_map_type
::
apply
<
double
,
GraphInterface
::
vertex_index_map_t
>::
type
vangle_t
;
vangle_t
::
unchecked_t
angle
(
get
(
vertex_index
,
g
),
num_vertices
(
g
));
double
d_sum
=
0
;
vector
<
vertex_t
>&
outer_layer
=
layers
.
back
();
for
(
size_t
i
=
0
;
i
<
outer_layer
.
size
();
++
i
)
d_sum
+=
count
[
outer_layer
[
i
]];
for
(
size_t
i
=
0
;
i
<
outer_layer
.
size
();
++
i
)
angle
[
outer_layer
[
i
]]
=
(
i
*
2
*
M_PI
*
count
[
outer_layer
[
i
]])
/
d_sum
;
for
(
size_t
i
=
0
;
i
<
layers
.
size
();
++
i
)
{
vector
<
vertex_t
>&
vs
=
layers
[
layers
.
size
()
-
1
-
i
];
for
(
size_t
j
=
0
;
j
<
vs
.
size
();
++
j
)
{
vertex_t
v
=
vs
[
j
];
d_sum
=
0
;
typename
graph_traits
<
Graph
>::
out_edge_iterator
e
,
e_end
;
for
(
tie
(
e
,
e_end
)
=
out_edges
(
v
,
g
);
e
!=
e_end
;
++
e
)
{
vertex_t
w
=
target
(
*
e
,
g
);
d_sum
+=
count
[
w
];
}
for
(
tie
(
e
,
e_end
)
=
out_edges
(
v
,
g
);
e
!=
e_end
;
++
e
)
{
vertex_t
w
=
target
(
*
e
,
g
);
angle
[
v
]
+=
angle
[
w
]
*
count
[
w
]
/
d_sum
;
}
double
d
=
level
[
v
]
*
r
;
tpos
[
v
].
resize
(
2
);
tpos
[
v
][
0
]
=
d
*
cos
(
angle
[
v
]);
tpos
[
v
][
1
]
=
d
*
sin
(
angle
[
v
]);
}
}
}
};
void
get_radial
(
GraphInterface
&
gi
,
boost
::
any
otpos
,
boost
::
any
olevels
,
size_t
root
,
bool
weighted
,
double
r
)
{
run_action
<
graph_tool
::
detail
::
always_directed
>
()
(
gi
,
bind
<
void
>
(
do_get_radial
(),
_1
,
_2
,
_3
,
root
,
weighted
,
r
),
vertex_scalar_vector_properties
(),
vertex_scalar_properties
())(
otpos
,
olevels
);
}
#include
<boost/python.hpp>
void
export_radial
()
{
python
::
def
(
"get_radial"
,
&
get_radial
);
}
src/graph_tool/draw/__init__.py
View file @
ae9857c0
...
...
@@ -34,6 +34,7 @@ Layout algorithms
sfdp_layout
fruchterman_reingold_layout
arf_layout
radial_tree_layout
random_layout
get_hierarchy_control_points
...
...
@@ -68,9 +69,10 @@ from __future__ import division, absolute_import, print_function
from
..
import
GraphView
,
_check_prop_vector
,
group_vector_property
,
\
ungroup_vector_property
,
infect_vertex_property
,
_prop
,
_get_rng
from
..
topology
import
max_cardinality_matching
,
max_independent_vertex_set
,
\
label_components
,
pseudo_diameter
label_components
,
pseudo_diameter
,
shortest_distance
from
..
community
import
condensation_graph
from
..
stats
import
label_parallel_edges
from
..
generation
import
predecessor_tree
import
numpy.random
from
numpy
import
sqrt
import
sys
...
...
@@ -82,6 +84,7 @@ dl_import("from . import libgraph_tool_layout")
__all__
=
[
"graph_draw"
,
"graphviz_draw"
,
"fruchterman_reingold_layout"
,
"arf_layout"
,
"sfdp_layout"
,
"random_layout"
,
"radial_tree_layout"
,
"cairo_draw"
,
"prop_to_size"
,
"get_hierarchy_control_points"
]
...
...
@@ -699,6 +702,69 @@ def sfdp_layout(g, vweight=None, eweight=None, pin=None, groups=None, C=0.2,
verbose
)
return
pos
def
radial_tree_layout
(
g
,
root
,
weighted
=
False
,
r
=
1.
):
r
"""Computes a radial layout of the graph according to the minimum spanning
tree centered at the ``root`` vertex.
Parameters
----------
g : :class:`~graph_tool.Graph`
Graph to be used.
root : :class:`~graph_tool.Vertex` or ``int``
The root of the radial tree.
weighted : ``bool`` (optional, default: ``False``)
If true, the angle between the child branches will be computed according
to weight of the entire sub-branches.
r : ``float`` (optional, default: ``1.``)
Layer spacing.
Returns
-------
pos : :class:`~graph_tool.PropertyMap`
A vector-valued vertex property map with the coordinates of the
vertices.
Notes
-----
This algorithm has complexity :math:`O(V + E)`.
Examples
--------
.. testcode::
:hide:
np.random.seed(42)
gt.seed_rng(42)
>>> g = gt.price_network(1000)
>>> pos = gt.radial_tree_layout(g, g.vertex(0))
>>> gt.graph_draw(g, pos=pos, output="graph-draw-radial.pdf")
<...>
.. testcode::
:hide:
gt.graph_draw(g, pos=pos, output="graph-draw-radial.png")
.. figure:: graph-draw-radial.*
:align: center
Radial tree layout of a Price network.
"""
levels
,
pred_map
=
shortest_distance
(
GraphView
(
g
,
directed
=
False
),
root
,
pred_map
=
True
)
t
=
predecessor_tree
(
g
,
pred_map
)
pos
=
t
.
new_vertex_property
(
"vector<double>"
)
levels
=
t
.
own_property
(
levels
)
libgraph_tool_layout
.
get_radial
(
t
.
_Graph__graph
,
_prop
(
"v"
,
g
,
pos
),
_prop
(
"v"
,
g
,
levels
),
int
(
root
),
weighted
,
r
)
return
g
.
own_property
(
pos
)
try
:
from
.cairo_draw
import
graph_draw
,
cairo_draw
,
get_hierarchy_control_points
except
ImportError
:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment