'Graph Tool's edge_gradient property

I would like to use the edge_gradient property on Graph Tool's gt.graph_draw() in order to better visualize the direction of connections in plots which are too crowded for markers such as arrows.

From the description in the docs, it seems this is what this property should do. Currently, however, it only lets me set the edges to a solid color.

I am using the property like so:

egradient = g.new_edge_property('vector<double>')
g.edge_properties['egradient'] = egradient
e = g.add_edge(v1, v2)
egradient[e] = (0.9, 0.329,0.282,0.478,1)
...
gt.graph_draw(g, ... edge_gradient=g.edge_properties["egradient"])

The appearance remains unchanged if I modify the first value in (0.9, 0.329,0.282,0.478,1) - and if I try to pass it a list of tuples I get this from the graph tool internals:

TypeError: float() argument must be a string or a number

How can I achieve what I am looking for in graph tool? If I can't, then what else is the first value in the edge gradient 5-tuple actually good for?



Solution 1:[1]

edge_gradient actually expects a list of integers, not a list of tuples. I made the same mistake at first.

Example: If you want to go from white to black, your `edge_gradient parameter should look like this:

#              o  r  g  b  a  o  r  g  b  a
edge_gradient=[0, 1, 1, 1, 1, 1, 0, 0, 0, 1]

That's what the docs mean by, "Each group of 5 elements is interpreted as [o, r, g, b, a] where o is the offset in the range [0, 1] and the remaining values specify the colors.

It gets a little tough to read, so I separate my stop points and format them like this:

#              offset  r  g  b  a
edge_gradient=[0,      1, 1, 1, 1, \
               0.5,    0, 0, 0, 1, \
               1,      1, 0, 0, 1]

Which fades from white to black to red. ...In theory, at least. I have had trouble getting edge_gradient to work with more than two gradient stop points. I always end up with some edges coloured like the list I pass to the edge_gradient property, and the rest with strange behaviour, like having the final colour in the middle.

Solution 2:[2]

# Set the gradients [must be same shape, not ragged array ex: (1, 15)]
num_edges = 2
grad_length = 15

## 3 Stops: red to grey to blue
egrad_1 = np.asarray([  0,   1,   0,   0, 1, 
                      0.5, 0.8, 0.8, 0.8, 1,
                        1,   0,   0,   1, 1]) 
## 3 Stops: grey to grey to grey
egrad_2 = np.asarray([  0, 0.8, 0.8, 0.8, 1, 
                      0.5, 0.8, 0.8, 0.8, 1,
                        1, 0.8, 0.8, 0.8, 1]) 


# Place into array of shape (num_edges, grad_length)
gradient_list = np.asarray([egrad_1, egrad_2])

# Create graph and add vertices and edges
g1 = gt.Graph(directed=False)
g1.ep.edge_gradient = g1.new_edge_property("vector<double>")
g1v1 = g1.add_vertex()
g1v2 = g1.add_vertex()
e1 = g1.add_edge(g1v1, g1v2)
e2 = g1.add_edge(g1v1, g1v1)

# Set property map
g1.ep.edge_gradient.set_2d_array(np.transpose(gradient_list))

# Draw the graph
gt.graph_draw(g1, edge_gradient=g1.ep.edge_gradient)

Graph Result

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2