Hello, I'm trying to find a way to spatially separate edges from each other in cases where two nodes are connected by many edges. This is done by default but I'd like them to be even more spread out so that I can put readable text on each edge. I've a feeling this can be accomplished by edge_control_points but can't figure out how to specify appropriate bézier control points. Any hints would be greatly appreciated ! Best, -bertrand
Hi Bertrand, As you correctly guessed you'll need to manually control the Bezier spline for each edge. Each edge can be composed of several Bezier segment. Each segment is controlled by two intermediate control points (x1, y1), (x2, y2) and the final point (x3, y3). All these points are specified as floats on a [0, 1] scale where (0, 0) is the position of the source vertex and (1, 0) is the position of the target vertex. What you'll need is an edge property map of type vector<double> and each spline segment will be specified by 6 consecutive floats x1, y1, x2, y2, x3, y3 in this array. To get an intuition about Bezier splines, take a look at https://vimeo.com/106757336 One subtlety that took me a while to figure out is that it looks like the first two floats in this array should not be the coordinate of the first control point of the first spline segment, but the initial point wherefrom the total spline should start start, namely (0, 0) in most cases. This is not specified in the documentation and I believe it comes from the way splines segments are incrementally passed to the cairo backend. Here's an example in IPython notebook %matplotlib inline import graph_tool.all as gt foo = gt.Graph() newe = foo.add_edge(0, 1) foo.add_vertex(n=4) foopos = foo.new_vertex_property('vector<double>') ctlpts = foo.new_edge_property('vector<double>') foopos = gt.random_layout(foo) ctlpts[newe] = [0.0, 0.0, 0.2, -0.5, 0.3, 0.5, 0.5, 0.0, 0.7, -0.5, 0.8, 0.5, 1.0, 0.0] gt.graph_draw(foo, pos=foopos, edge_control_points=ctlpts, vertex_size=10, inline=True) In this case, the edge connecting vertices 0 and 1 is composed of two splines segments given by Initial point: (0.0, 0.0) Segment 1 control point 1: (0.2, -0.5) Segment 1 control point 2: (0.3, 0.5) Segment 1 end point: (0.5, 0.0) Segment 2 control point 1: (0.7, -0.5) Segment 2 control point 2: (0.8, 0.5) Segment 2 end point: (1.0, 0.0) Segment 1 therefore ends half-way (x=0.5) and in line (y=0.0) between the two vertices. Because of the way cairo takes splines segment, the end point of a segment serves as the initial point of the next segment so you don't have to specify it again. To actually answer your question, I guess you could iterate the control point property map and stretch the y coordinate of all control points using a scale factor. Philippe -- View this message in context: http://main-discussion-list-for-the-graph-tool-project.982480.n3.nabble.com/... Sent from the Main discussion list for the graph-tool project mailing list archive at Nabble.com.
participants (2)
-
Bertrand Chapleau -
Philippe Doucet Beaupre