5
$\begingroup$

Following up on a previous question about how to color the nodes (vertices) of a network (graph) according to a color scaling of a property of those nodes, I'm now asking basically the same thing about edges:

How can I color the edges of a graph (using a gradient color scheme) according to the weight (or other property) of the edges using GraphPlot?

It's easy if one just wants some conditional coloring (using "If[]"), but I (and I guess many people) want color scaling. Although there are some examples here that don't use GraphPlot, they won't work for me.

I did find one post that included something like an answer, but it was so complicated that I couldn't port it over to my case. So I'm trying to use the EdgeRenderingFunction and I can't get it to work.

To make this concrete, Here is a graph and a plot of a graph with edge weights between -1 and 1:

SomeGraph = WeightedAdjacencyGraph[{{∞, 1, .8, ∞, -1}, {1, ∞, .6, -1, ∞},
            {1, .6, ∞, ∞, -.6}, {∞, -0.5, ∞, ∞, 1}, {-1, ∞, -1, 1, ∞}},
            DirectedEdges -> False];
TheCoordinates = {{0, 1},{0, 2}, {0, 3}, {2, 1.5}, {2,2.5}};
PlotOfSomeGraph=GraphPlot[SomeGraph,
                          VertexCoordinateRules-> TheCoordinates, 
                          VertexRenderingFunction -> 
                    (Inset[Graphics[{Gray, Disk[{0, 0}, .01]}, ImageSize -> 17], #] &)]

And now I'd like to add an EdgeRenderingFunction to that GraphPlot so that they are colored on a rescaled reversed temperature map. I know that some adaptation of

EdgeRenderingFunction -> 
  ({Opacity[0.5],ColorData[{"TemperatureMap", "Reverse"}][Rescale[...]], Line[#1]} &)

And to fill in the gap I can access some edge information using #1 for the endpoint coordinates, #2 for the start and ending vertices, and #3 for the edge label.

I might be able to kludge something using EdgeLabels, but because coloring edges by weight (or other property) is a basic feature of all other network tools I expect (or at least I expected) a simple way to do this in Mathematica (version 10.1).

$\endgroup$
  • $\begingroup$ any reason to use GraphPlot instead Graph? $\endgroup$ – halmir Jul 21 '15 at 21:25
  • $\begingroup$ Yes, but mostly because I had used it before. However, if you would like to provide an answer using Graph showing how it is just as good or better, then I would certainly be interested in seeing that and it would also benefit the community. $\endgroup$ – Aaron Bramson Jul 23 '15 at 16:34
  • $\begingroup$ Welcome to Mathematica.SE! I suggest the following: 0) Browse the common pitfalls question 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Read the faq! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$ – Dr. belisarius Jul 23 '15 at 16:40
4
$\begingroup$
wam = WeightedAdjacencyMatrix@SomeGraph;
erf = ({ColorData[{"TemperatureMap", "Reverse"}][Rescale[wam[[Sequence @@ #2]],
                                                              {Min@wam, Max@wam}]],
        Line[#1]} &);
PlotOfSomeGraph = GraphPlot[
                            SomeGraph,
                            VertexCoordinateRules -> TheCoordinates,
                            EdgeRenderingFunction -> (erf)]

Mathematica graphics


Edit

Packing it as a function

erf[wam_] := {ColorData["MintColors"][Rescale[wam[[Sequence@@#2]], {Min@wam, Max@wam}]], 
                Line[#1]}&;
gp[wam_] := GraphPlot[WeightedAdjacencyGraph[wam, DirectedEdges -> False], 
                      Method -> "CircularEmbedding",
                      EdgeRenderingFunction -> (erf[wam])]

gp[SparseArray[{i_, j_} :> i + j, {15, 15}]]

Mathematica graphics

$\endgroup$
  • $\begingroup$ That works, but I don't understand it 100%. What work is being done by "Sequence @@ #2" (= "Apply[Sequence,#2]" in which #2 is the pair of vertices for the edge)? I know the output of that part is "Sequence[v1,v2]", but I don't understand how that is pulling the correct item from the adjacency matrix (while using the list {v1,v2} fails to work). Could you please elaborate? $\endgroup$ – Aaron Bramson Jul 23 '15 at 16:29
  • $\begingroup$ wam[[Sequence @@ #2]] is retrieving the weight of the edge between v1 and v2 $\endgroup$ – Dr. belisarius Jul 23 '15 at 16:59
  • $\begingroup$ Right, "but I don't understand how that is pulling the correct item from the adjacency matrix (while using the list {v1,v2} fails to work). Could you please elaborate? " Specifically, why is a "sequence" the right thing for the job? It's not clear from the definitions and, as usual, the official documentation is totally worthless. $\endgroup$ – Aaron Bramson Jul 24 '15 at 18:53
  • $\begingroup$ @AaronBramson It isn't a problem with this particular piece of documentation, but a general Mathematica thing. Try this list = {{a,b},{ c, d}, {e,f}}; ind = {1,2}; Print@list[[ind]]; Print@list[[Sequence@@ind]]; $\endgroup$ – Dr. belisarius Jul 24 '15 at 18:59
  • $\begingroup$ I see, so list[[Sequence@@ind]] equivalent to list[[ind[[1]]]][[ind[[2]]]] because there are only two elements of ind, but is more general. Your way of writing it is less intuitive (less noob-friendly) but now that I understand how it translates into basic commands it's clearly better to write it your way. $\endgroup$ – Aaron Bramson Jul 24 '15 at 19:44
3
$\begingroup$

With IGraph/M, colouring based on edge weights:

Graph[SomeGraph, EdgeStyle -> AbsoluteThickness[4], VertexCoordinates -> TheCoordinates] // 
  IGEdgeMap[ColorData["Rainbow"], EdgeStyle -> Rescale@*IGEdgeProp[EdgeWeight]]

Mathematica graphics

Notice how the per-vertex setting of the EdgeStyle (by IGEdgeMap) did not revert the global EdgeStyle setting for thickness.

$\endgroup$
2
$\begingroup$

You can also set EdgeStyle to do this (using Graph):

Graph[SomeGraph, 
 EdgeStyle -> 
  Thread[EdgeList[
     SomeGraph] -> (Directive[Opacity[0.5], 
        ColorData[{"TemperatureMap", "Reverse"}][#]] & /@ 
      Rescale[PropertyValue[SomeGraph, EdgeWeight]])], 
 GraphStyle -> "ThickEdge", VertexCoordinates -> TheCoordinates]

enter image description here

$\endgroup$
  • $\begingroup$ This looks good too. I typically have a few thousand sparsely connected nodes that are also sized and colored by data...and hundreds of those per analysis. Any idea if there is a clear performance winner between Graph vs GraphPlot and Graph3D vs GraphPlot3D? $\endgroup$ – Aaron Bramson Jul 24 '15 at 19:27
1
$\begingroup$
SetProperty[SomeGraph, {ImagePadding -> 10 , VertexCoordinates -> TheCoordinates,
  EdgeStyle -> {e_ :> {CapForm["Round"], Thickness[.1], 
   ColorData[{"TemperatureMap", "Reverse"}]@
     Rescale[PropertyValue[SomeGraph, EdgeWeight]][[EdgeIndex[SomeGraph, e]]]}}}]

enter image description here

Use Thickness[.001 + Abs[Normalize[PropertyValue[SomeGraph, EdgeWeight]][[EdgeIndex[SomeGraph, e]]]]/5] to get

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.