Commit 00a0e7ef authored by Tiago Peixoto's avatar Tiago Peixoto

Fix draw_hierarchy() for filtered graphs

parent 2291b947
...@@ -154,8 +154,7 @@ void tree_path(Graph& g, size_t s, size_t t, vector<size_t>& path) ...@@ -154,8 +154,7 @@ void tree_path(Graph& g, size_t s, size_t t, vector<size_t>& path)
t_root.push_back(u); t_root.push_back(u);
} }
path = s_root; path = s_root;
for (typeof(t_root.rbegin()) iter = t_root.rbegin(); for (auto iter = t_root.rbegin(); iter != t_root.rend(); ++iter)
iter != t_root.rend(); ++iter)
path.push_back(*iter); path.push_back(*iter);
} }
......
...@@ -27,7 +27,7 @@ void predecessor_graph(GraphInterface& gi, GraphInterface& gpi, ...@@ -27,7 +27,7 @@ void predecessor_graph(GraphInterface& gi, GraphInterface& gpi,
boost::any pred_map) boost::any pred_map)
{ {
run_action<>()(gi, std::bind(get_predecessor_graph(), placeholders::_1, run_action<>()(gi, std::bind(get_predecessor_graph(), placeholders::_1,
gi.GetVertexIndex(), std::ref(gpi.GetGraph()), std::ref(gpi.GetGraph()),
placeholders::_2), placeholders::_2),
vertex_scalar_properties())(pred_map); vertex_scalar_properties())(pred_map);
} }
...@@ -29,37 +29,26 @@ using namespace boost; ...@@ -29,37 +29,26 @@ using namespace boost;
struct get_predecessor_graph struct get_predecessor_graph
{ {
template <class Graph, class IndexMap, class PredGraph, class PredMap> template <class Graph, class PredGraph, class PredMap>
void operator()(Graph& g, IndexMap vertex_index, PredGraph& pg, void operator()(Graph& g, PredGraph& pg, PredMap pred_map) const
PredMap pred_map) const
{ {
unchecked_vector_property_map<size_t,IndexMap> while (num_vertices(pg) < num_vertices(g))
index_map(vertex_index, num_vertices(g));
size_t count = 0;
typename graph_traits<Graph>::vertex_iterator v,v_end;
for (tie(v,v_end) = vertices(g); v != v_end; ++v)
{
index_map[*v] = count++;
add_vertex(pg); add_vertex(pg);
}
for (tie(v,v_end) = vertices(g); v != v_end; ++v) for (auto v : vertices_range(g))
{ {
size_t pred_i = get(pred_map, *v); auto pred_i = get(pred_map, v);
if (pred_i >= num_vertices(g)) if (pred_i >= num_vertices(g))
continue; continue;
typename graph_traits<Graph>::vertex_descriptor pred = auto pred = vertex(pred_i, g);
vertex(pred_i, g);
if (pred == graph_traits<Graph>::null_vertex()) if (pred == graph_traits<Graph>::null_vertex())
continue; continue;
if (pred != *v) if (pred != v)
{ {
typename graph_traits<PredGraph>::vertex_descriptor s, t; auto s = vertex(pred, pg);
s = vertex(index_map[pred], pg); auto t = vertex(v, pg);
t = vertex(index_map[*v], pg);
add_edge(s, t, pg); add_edge(s, t, pg);
} }
} }
......
...@@ -42,20 +42,20 @@ struct do_get_radial ...@@ -42,20 +42,20 @@ struct do_get_radial
if (!weighted) if (!weighted)
{ {
typename graph_traits<Graph>::vertex_iterator v, v_end; for (auto v : vertices_range(g))
for(tie(v, v_end) = vertices(g); v != v_end; ++v) count[v] = 1;
count[*v] = 1;
} }
else else
{ {
deque<vertex_t> q; deque<vertex_t> q;
typename graph_traits<Graph>::vertex_iterator v, v_end; for (auto v : vertices_range(g))
for(tie(v, v_end) = vertices(g); v != v_end; ++v) {
if (out_degree(*v, g) == 0) if (out_degree(v, g) == 0)
{ {
q.push_back(*v); q.push_back(v);
count[*v] = 1; count[v] = 1;
} }
}
typedef property_map_type::apply<uint8_t, GraphInterface::vertex_index_map_t>::type typedef property_map_type::apply<uint8_t, GraphInterface::vertex_index_map_t>::type
vmark_t; vmark_t;
...@@ -65,10 +65,9 @@ struct do_get_radial ...@@ -65,10 +65,9 @@ struct do_get_radial
{ {
vertex_t v = q.front(); vertex_t v = q.front();
q.pop_front(); q.pop_front();
typename graph_traits<Graph>::in_edge_iterator e, e_end; for (auto e : in_edges_range(v, g))
for(tie(e, e_end) = in_edges(v, g); e != e_end; ++e)
{ {
vertex_t w = source(*e, g); vertex_t w = source(e, g);
count[w] += count[v]; count[w] += count[v];
if (!mark[w]) if (!mark[w])
{ {
...@@ -93,10 +92,9 @@ struct do_get_radial ...@@ -93,10 +92,9 @@ struct do_get_radial
for (size_t i = 0; i < last_layer.size(); ++i) for (size_t i = 0; i < last_layer.size(); ++i)
{ {
vertex_t v = last_layer[i]; vertex_t v = last_layer[i];
typename graph_traits<Graph>::out_edge_iterator e, e_end; for (auto e : out_edges_range(v, g))
for(tie(e, e_end) = out_edges(v, g); e != e_end; ++e)
{ {
vertex_t w = target(*e, g); vertex_t w = target(e, g);
new_layer.push_back(w); new_layer.push_back(w);
if (int(layers.size()) - 1 == int(level[w])) if (int(layers.size()) - 1 == int(level[w]))
...@@ -133,15 +131,14 @@ struct do_get_radial ...@@ -133,15 +131,14 @@ struct do_get_radial
{ {
vertex_t v = vs[j]; vertex_t v = vs[j];
d_sum = 0; d_sum = 0;
typename graph_traits<Graph>::out_edge_iterator e, e_end; for (auto e : out_edges_range(v, g))
for(tie(e, e_end) = out_edges(v, g); e != e_end; ++e)
{ {
vertex_t w = target(*e, g); vertex_t w = target(e, g);
d_sum += count[w]; d_sum += count[w];
} }
for(tie(e, e_end) = out_edges(v, g); e != e_end; ++e) for (auto e : out_edges_range(v, g))
{ {
vertex_t w = target(*e, g); vertex_t w = target(e, g);
angle[v] += angle[w] * count[w] / d_sum; angle[v] += angle[w] * count[w] / d_sum;
} }
double d = level[v] * r; double d = level[v] * r;
......
...@@ -1722,7 +1722,13 @@ def get_hierarchy_tree(state, empty_branches=True): ...@@ -1722,7 +1722,13 @@ def get_hierarchy_tree(state, empty_branches=True):
t = Graph() t = Graph()
t.add_vertex(g.num_vertices()) if g.get_vertex_filter()[0] is None:
t.add_vertex(g.num_vertices())
else:
t.add_vertex(g.num_vertices(ignore_filter=True))
filt = g.get_vertex_filter()
t.set_vertex_filter(t.own_property(filt[0].copy()),
filt[1])
label = t.vertex_index.copy("int") label = t.vertex_index.copy("int")
order = t.own_property(g.degree_property_map("total").copy()) order = t.own_property(g.degree_property_map("total").copy())
...@@ -1738,15 +1744,19 @@ def get_hierarchy_tree(state, empty_branches=True): ...@@ -1738,15 +1744,19 @@ def get_hierarchy_tree(state, empty_branches=True):
for e in s.edges(): for e in s.edges():
if e.source() == e.target(): if e.source() == e.target():
count[e] /= 2 count[e] /= 2
vs = [t.vertex(vi) for vi in range(pos, t.num_vertices())] vs = []
vs = sorted(vs, key=lambda v: (s.vertex(int(v) - pos).out_degree(count) + pvs = {}
s.vertex(int(v) - pos).in_degree(count))) for vi in range(pos, t.num_vertices()):
vs.append(t.vertex(vi, use_index=False))
pvs[vs[-1]] = vi - pos
vs = sorted(vs, key=lambda v: (s.vertex(pvs[v]).out_degree(count) +
s.vertex(pvs[v]).in_degree(count)))
for vi, v in enumerate(vs): for vi, v in enumerate(vs):
order[v] = vi order[v] = vi
for vi, v in enumerate(g.vertices()): for vi, v in enumerate(g.vertices()):
w = t.vertex(vi + last_pos) w = t.vertex(vi + last_pos, use_index=False)
u = t.vertex(b[v] + pos) u = t.vertex(b[v] + pos, use_index=False)
t.add_edge(u, w) t.add_edge(u, w)
last_pos = pos last_pos = pos
...@@ -1759,7 +1769,7 @@ def get_hierarchy_tree(state, empty_branches=True): ...@@ -1759,7 +1769,7 @@ def get_hierarchy_tree(state, empty_branches=True):
vmask = t.new_vertex_property("bool") vmask = t.new_vertex_property("bool")
vmask.a = True vmask.a = True
for vi in range(state.g.num_vertices(), t.num_vertices()): for vi in range(state.g.num_vertices(), t.num_vertices()):
v = t.vertex(vi) v = t.vertex(vi, use_index=False)
if v.out_degree() == 0: if v.out_degree() == 0:
vmask[v] = False vmask[v] = False
while v.in_degree() > 0: while v.in_degree() > 0:
......
...@@ -1321,7 +1321,9 @@ def get_hierarchy_control_points(g, t, tpos, beta=0.8, cts=None): ...@@ -1321,7 +1321,9 @@ def get_hierarchy_control_points(g, t, tpos, beta=0.8, cts=None):
else: else:
beta = beta.copy("double") beta = beta.copy("double")
libgraph_tool_draw.get_cts(u._Graph__graph, tu._Graph__graph, tu = GraphView(tu, skip_vfilt=True)
libgraph_tool_draw.get_cts(u._Graph__graph,
tu._Graph__graph,
_prop("v", tu, tpos), _prop("v", tu, tpos),
_prop("e", u, beta), _prop("e", u, beta),
_prop("e", u, cts)) _prop("e", u, cts))
...@@ -1540,21 +1542,22 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1540,21 +1542,22 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
vorder = None vorder = None
if pos is not None: if pos is not None:
x, y = ungroup_vector_property(pos, [0, 1]) x, y = ungroup_vector_property(pos, [0, 1])
x.a -= x.a.mean() x.fa -= x.fa.mean()
y.a -= y.a.mean() y.fa -= y.fa.mean()
angle = g.new_vertex_property("double") angle = g.new_vertex_property("double")
angle.a = (numpy.arctan2(y.a, x.a) + 2 * numpy.pi) % (2 * numpy.pi) angle.fa = (numpy.arctan2(y.fa, x.fa) + 2 * numpy.pi) % (2 * numpy.pi)
vorder = angle vorder = angle
tpos = radial_tree_layout(t, root=t.vertex(t.num_vertices() - 1), tpos = radial_tree_layout(t, root=t.vertex(t.num_vertices() - 1,
use_index=False),
rel_order=vorder) rel_order=vorder)
elif layout == "sfdp": elif layout == "sfdp":
if pos is None: if pos is None:
tpos = sfdp_layout(t) tpos = sfdp_layout(t)
else: else:
x, y = ungroup_vector_property(pos, [0, 1]) x, y = ungroup_vector_property(pos, [0, 1])
x.a -= x.a.mean() x.fa -= x.fa.mean()
y.a -= y.a.mean() y.fa -= y.fa.mean()
K = numpy.sqrt(x.a.std() + y.a.std()) / 10 K = numpy.sqrt(x.fa.std() + y.fa.std()) / 10
tpos = t.new_vertex_property("vector<double>") tpos = t.new_vertex_property("vector<double>")
for v in t.vertices(): for v in t.vertices():
if int(v) < g.num_vertices(): if int(v) < g.num_vertices():
...@@ -1562,7 +1565,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1562,7 +1565,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
else: else:
tpos[v] = [0, 0] tpos[v] = [0, 0]
pin = t.new_vertex_property("bool") pin = t.new_vertex_property("bool")
pin.a[:g.num_vertices()] = True pin.a[:g.num_vertices(True)] = True
tpos = sfdp_layout(t, K=K, pos=tpos, pin=pin, multilevel=False) tpos = sfdp_layout(t, K=K, pos=tpos, pin=pin, multilevel=False)
else: else:
tpos = t.own_property(layout) tpos = t.own_property(layout)
...@@ -1612,7 +1615,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1612,7 +1615,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
val = edge_color val = edge_color
clrs = [g.new_edge_property("double") for i in range(4)] clrs = [g.new_edge_property("double") for i in range(4)]
for i in range(4): for i in range(4):
clrs[i].a = val[i] clrs[i].fa = val[i]
edge_color = group_vector_property(clrs) edge_color = group_vector_property(clrs)
else: else:
z = g.new_edge_property("double", 0) z = g.new_edge_property("double", 0)
...@@ -1643,7 +1646,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1643,7 +1646,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
tlabels = t.new_vertex_property("string") tlabels = t.new_vertex_property("string")
t_orig = t t_orig = t
t = GraphView(t, vfilt=lambda v: int(v) >= g.num_vertices()) t = GraphView(t, vfilt=lambda v: int(v) >= g.num_vertices(True))
if verbose: if verbose:
print("joining graphs") print("joining graphs")
props = [(pos, tpos), props = [(pos, tpos),
...@@ -1655,7 +1658,8 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1655,7 +1658,8 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
(args.get("edge_text", g.new_edge_property("string")).copy("string"), (args.get("edge_text", g.new_edge_property("string")).copy("string"),
edge_labels), edge_labels),
(g.vertex_index, tb), (g.vertex_index, tb),
(vlabels, tlabels)] (vlabels, tlabels),
(b, None)]
# propagate all other properties in args # propagate all other properties in args
arg_pos = {} arg_pos = {}
...@@ -1677,7 +1681,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1677,7 +1681,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
elabels = props[6] elabels = props[6]
tb = props[7] tb = props[7]
vertex_text = props[8] vertex_text = props[8]
b = u.own_property(b) b = props[9]
for a, v in arg_pos.items(): for a, v in arg_pos.items():
args[a] = props[v] args[a] = props[v]
...@@ -1695,15 +1699,15 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1695,15 +1699,15 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
vsize = prop_to_size(u.degree_property_map("total"), 5, 20) vsize = prop_to_size(u.degree_property_map("total"), 5, 20)
if "vertex_size" in args: if "vertex_size" in args:
vsize.a[:g.num_vertices()] = args["vertex_size"].a[:g.num_vertices()] vsize.a[:g.num_vertices()] = args["vertex_size"].fa[:g.num_vertices()]
del args["vertex_size"] del args["vertex_size"]
if vsize is not None: if vsize is not None:
vsize.a[g.num_vertices():] = vsize.a[g.num_vertices():].mean() * hsize_scale * 1.5 vsize.a[g.num_vertices():] = vsize.a[g.num_vertices():].mean() * hsize_scale * 1.5
ems = epw.copy() ems = epw.copy()
ems.a *= 2.75 ems.fa *= 2.75
ems.a[g.num_edges():] = numpy.sqrt(vsize.a[g.num_vertices():].mean() * hsize_scale * 1.5) * 2 ems.a[g.num_edges():] = numpy.sqrt(vsize.fa[g.num_vertices():].mean() * hsize_scale * 1.5) * 2
vsize.a[:g.num_vertices()] *= vsize_scale vsize.a[:g.num_vertices()] *= vsize_scale
...@@ -1809,12 +1813,13 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1809,12 +1813,13 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
no_main=True) no_main=True)
if key_id == ord('r'): if key_id == ord('r'):
x, y = ungroup_vector_property(pos, [0, 1]) x, y = ungroup_vector_property(pos, [0, 1])
x.a -= x.a.mean() x.fa -= x.fa.mean()
y.a -= y.a.mean() y.fa -= y.fa.mean()
angle = gg.new_vertex_property("double") angle = gg.new_vertex_property("double")
angle.a = (numpy.arctan2(y.a, x.a) + 2 * numpy.pi) % (2 * numpy.pi) angle.fa = (numpy.arctan2(y.fa, x.fa) + 2 * numpy.pi) % (2 * numpy.pi)
tpos = radial_tree_layout(t_orig, tpos = radial_tree_layout(t_orig,
root=t_orig.vertex(t_orig.num_vertices() - 1), root=t_orig.vertex(t_orig.num_vertices() - 1,
use_index=False),
rel_order=angle) rel_order=angle)
gg.copy_property(tpos, pos) gg.copy_property(tpos, pos)
update_cts(widget, gg, picked, pos, vprops, eprops) update_cts(widget, gg, picked, pos, vprops, eprops)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment