I am trying to plot a network with colored links and nodes. I would like to color links with a gradient depending on the colors of its endpoints/nodes. For instance, a link between a blue and a red node should have a linear gradient between blue and red. I would also like for links to be curved so a I am using also a BezierCurve function.

In order to obtain the gradient on the BezierCurve I am using VertexColors, which however works only on the Line graphics. So what I am doing is: for every couple of nodes get their coordinates, interpolate and create a BezierFunction, run the BezierFunction over an evenly split range and get a collection of lines approximating a BezierCurve, then color the lines.

However, I am unable to obtain colored links and would like to know where is the problem. The code is this one:

 versiz = {1 -> 0.8317766166719344, 2 -> 0.7193685818395111,
3 -> 0.6238324625039507, 4 -> 0.7917171988845775,
5 -> 0.769484807238461, 6 -> 0.6907755278982137,
7 -> 0.583773044716594, 8 -> 0.48283137373023005,
9 -> 0.48283137373023005, 10 -> 0.48283137373023005,
11 -> 0.48283137373023005, 12 -> 0.4158883083359672,
13 -> 0.48283137373023005, 14 -> 0.5375278407684164,
15 -> 0.4158883083359672, 16 -> 0.4158883083359672,
17 -> 0.5375278407684164, 18 -> 0.4158883083359672,
19 -> 0.4158883083359672, 20 -> 0.4158883083359672};
cols = Table[If[RandomReal[] < 0.3, Red, Blue], {i, 1, 20}];

edges = {{1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1,
9}, {1, 10}, {1, 11}, {1, 14}, {1, 15}, {1, 16}, {1, 18}, {1,
19}, {1, 20}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 10}, {2,
11}, {2, 12}, {2, 13}, {2, 20}, {3, 4}, {3, 5}, {3, 6}, {3,
8}, {3, 9}, {3, 13}, {4, 5}, {4, 6}, {4, 10}, {4, 11}, {4,
12}, {4, 13}, {4, 14}, {4, 15}, {4, 16}, {4, 17}, {4, 18}, {5,
7}, {5, 8}, {5, 9}, {5, 12}, {5, 14}, {5, 15}, {5, 17}, {5,
18}, {5, 19}, {6, 7}, {6, 9}, {6, 11}, {6, 13}, {6, 16}, {6,
20}, {7, 8}, {7, 15}, {7, 19}, {8, 10}, {9, 17}, {10, 12}, {11,
18}, {13, 14}, {14, 16}, {14, 17}, {17, 19}, {17, 20}};

Graph[UndirectedEdge @@@ edges,
EdgeShapeFunction -> ({AbsoluteThickness[4],
Line[BezierFunction[{#1[[1]], #1[[1]] +
0.5 RotationMatrix[.3].(#1[[2]] - #1[[1]]), #1[[2]]}] /@
Range[0, 1, 0.1],
VertexColors -> (Blend[cols[[List @@ #2]], #] & /@
Range[0, 1, 0.1])]} &), VertexSize -> versiz,


I am afraid that the Blend function is not working properly here. If I substitute #2 with fixed colors, I do get colored links (although they are static):

 Graph[UndirectedEdge @@@ edges,
EdgeShapeFunction -> ({AbsoluteThickness[4],
Line[BezierFunction[{#1[[1]], #1[[1]] +
0.5 RotationMatrix[.3].(#1[[2]] - #1[[1]]), #1[[2]]}] /@
Range[0, 1, 0.1],
VertexColors -> (Blend[{Red, Blue}, #] & /@
Range[0, 1, 0.1])]} &), VertexSize -> versiz,


• Can you also post the exact code that does not work? The one in the question does work fine, I assume that you already substituted #2. Aug 29, 2018 at 15:11
• Thanks for the reply! I added also the code that does not work. Aug 29, 2018 at 15:46

You have a nested pure-function, both levels of which use Slot:

({AbsoluteThickness[4],
Line[BezierFunction[{#1[[1]], #1[[1]] +
0.5 RotationMatrix[.3].(#1[[2]] - #1[[1]]), #1[[2]]}] /@
Range[0, 1, 0.1],
VertexColors -> (Blend[cols[[List @@ #2]], #] & /@
Range[0, 1, 0.1])]} &)


You intend for the #2 to bind to the outer &, but it instead binds to the inner &. For situations like this, you can change one of these to a Function with named arguments:

Graph[UndirectedEdge @@@ edges,
EdgeShapeFunction -> ({AbsoluteThickness[4],
Line[BezierFunction[{#1[[1]], #1[[1]] +
0.5 RotationMatrix[.3].(#1[[2]] - #1[[1]]), #1[[2]]}] /@
Range[0, 1, 0.1],
VertexColors -> (Function[val, Blend[cols[[List @@ #2]], val]] /@
Range[0, 1, 0.1])]} &), VertexSize -> versiz,

• @MatheM - that looks like a separate issue. For the edge bundling layout, it seems that the EdgeShapeFunction is given not the line segments, but the control points for Bezier curve. Here is a modification that should do what you want. Aug 30, 2018 at 19:54