Message Boards Message Boards

1
|
8289 Views
|
6 Replies
|
14 Total Likes
View groups...
Share
Share this post:

Plot network with edges depending on weights?

I have the following weights and graph:

w = {2., 1., 0.5, 0.3, 1.2};
GraphPlot[{1 -> 2, 3 -> 1, 3 -> 2, 4 -> 1, 4 -> 2}]

What I want is to visualize the graph in such a way that edges have a different thickness and color proportionally, depending on the weights given.

Does anyone know how to do this in Mathematica?

Thanks in advance for any help!

6 Replies

I wrote a little guide that might be useful to you: On design of styles for small weighted graphs

https://community.wolfram.com/groups/-/m/t/838652

enter image description here

POSTED BY: Vitaliy Kaurov

With the IGraph/M package, it is easy to map one graph property into another one, e.g. to map edge weights into edge styles.

Here's an example weighted graph, with weights between 2 and 10.

g = RandomGraph[{10, 20}, EdgeWeight -> RandomReal[{2, 10}, 20]];

A helper function to normalize weights to between 0 and 1, which can then be easily used as an input to colour functions:

normalizeBy[f_] := Normalize[#, f] &;

Sometimes I simply use Rescale instead.

Now we use IGEdgeMap to do the mapping:

Legended[
 IGEdgeMap[
  Directive[AbsoluteThickness[5 #], ColorData["CandyColors"][#]] &,
  EdgeStyle -> normalizeBy[Max]@*IGEdgeProp[EdgeWeight],
  Graph[g, EdgeStyle -> Opacity[1]]
 ],
 BarLegend[{"CandyColors", {0, Max@IGEdgeProp[EdgeWeight][g]}}]
]

enter image description here

Let me know if anything is unclear in the code. The property mapping functions of the package are described here: http://szhorvat.net/mathematica/IGDocumentation/#property-handling-and-transformations

POSTED BY: Szabolcs Horvát

Amazing answer!

Thank you so much!

I've done some work over your code to reach this:

Networks

I hope your answer can be helpful also for other people =)

Let me help you with Wolfram Language programming because what you are writing is not idiomatic and because a good understanding of the fundamentals will get you a long way. Get rid of the indices, you don't need them. Use Thread to bring the x and y together. Also use it's idiomatic to use lower case starting letters for your own variables. And let's get the raw weight data out of the way.

x = {2000., 1000., 0., 1000., 0., 1000., 0.};(*X coordinates*)   
y = {2000., 2000., 2000., 1000., 1000., 0., 0.};(*Y coordinates*)
coordinates = Thread[{x, y}];
w = {9.59353, 17.6205, 30.5427, 22.4938, 20.8078, 16.8908, 15.662, 
   10.5943};

Again, use Thread to create your (unstyled) edges

edges = Thread[
  DirectedEdge[{1, 2, 2, 4, 4, 6, 3, 7}, {2, 3, 4, 5, 6, 7, 5, 5}]]

Use MapThread to style your edges. I've made up functions for color and thickness; you will want to use your own. Also lookup Rescale and MinMax. They are your friends.

(styledEdges = 
   MapThread[
    Property[#1, 
      EdgeStyle -> {Hue[Rescale[#2, MinMax[w], {0, 1}]], 
        Thickness[Rescale[#2, MinMax[w], {0.01, 0.02}]]}] &, {edges, 
     w}]) // Short

Now we just write:

g = Graph[styledEdges, VertexCoordinates -> coordinates, 
  VertexShapeFunction -> None] 

Let's make this a one-liner where I avoid creation of intermediate variables.

Module[{x, y, w,},
 x = {2000., 1000., 0., 1000., 0., 1000., 0.};
 y = {2000., 2000., 2000., 1000., 1000., 0., 0.};
 w = {9.59353, 17.6205, 30.5427, 22.4938, 20.8078, 16.8908, 15.662, 
   10.5943};
 Graph[MapThread[
   Property[#1, 
     EdgeStyle -> {Hue[Rescale[#2, MinMax[w], {0, 1}]], 
       Thickness[Rescale[#2, MinMax[w], {0.01, 0.02}]]}] &, {Thread[
     DirectedEdge[{1, 2, 2, 4, 4, 6, 3, 7}, {2, 3, 4, 5, 6, 7, 5, 
       5}]], w}], VertexCoordinates ->Thread[{x,y}], 
  VertexShapeFunction -> None]
 ]

And, of course, you could turn this into a function so it could handle different data and different edge decorations or whatever else you wanted.

aragonesGraph[edges_, weights_, coordinates_, decoratorFunction_,opts:OptionsPattern[Graph]] := 
 Graph[MapThread[decoratorFunction, {edges, weights}], 
  VertexCoordinates -> coordinates, VertexShapeFunction -> None,opts]

Then you could write this:

aragonesGraph[
 Thread[DirectedEdge[{1, 2, 2, 4, 4, 6, 3, 7}, {2, 3, 4, 5, 6, 7, 5, 
    5}]], {9.59353, 17.6205, 30.5427, 22.4938, 20.8078, 16.8908, 
  15.662, 10.5943}, 
 Thread[{{2000., 1000., 0., 1000., 0., 1000., 0.}, {2000., 2000., 
    2000., 1000., 1000., 0., 0.}}], 
 Property[#1, 
   EdgeStyle -> {Hue[Rescale[#2, MinMax[w], {0, 1}]], 
     Thickness[Rescale[#2, MinMax[w], {0.01, 0.02}]]}] &],Background->Yellow,PlotLabel->"My graph"]]

Or this

With[{edges= Thread[DirectedEdge[{1, 2, 2, 4, 4, 6, 3, 7}, {2, 3, 4, 5, 6, 7, 5, 
    5}]],
weights={9.59353, 17.6205, 30.5427, 22.4938, 20.8078, 16.8908, 
  15.662, 10.5943},
coordinates= Thread[{{2000., 1000., 0., 1000., 0., 1000., 0.}, {2000., 2000., 
    2000., 1000., 1000., 0., 0.}}]},
aragonesGraph[edges,weights, coordinates,
 Property[#1, 
   EdgeStyle -> {Hue[Rescale[#2, MinMax[w], {0.4, 0.7}]], 
     Thickness[Rescale[#2, MinMax[w], {0.01, 0.02}]]}] &, 
 EdgeShapeFunction -> 
  GraphElementData[{"CarvedArrow", "ArrowSize" -> .1}], 
 Background -> Orange, PlotLabel -> "My second graph"]
]

Anyway, this may be more than you wanted or needed to know to answer your particular time, but I thought it might prove helpful for you and others to see what you can do with a little more idiomatic code in the Wolfram Language.

POSTED BY: Seth Chandler

Thank you for your answer!

I've tried to apply your solution to my case, however I haven't succeeded so far, so I've developed a more elaborated example:

x={2000., 1000., 0., 1000., 0., 1000., 0.}; (*X coordinates*)
y={2000., 2000., 2000., 1000., 1000., 0., 0.}; (*Y coordinates*)
Nnodes=7; (*Number of nodes*)
Nedges=8; (*Number of edges*)
Nodes0={1, 2, 2, 4, 4, 6, 3, 7}; (*Initial nodes*)
Nodesf={2, 3, 4, 5, 6, 7, 5, 5}; (*Final nodes*)
Nodes = Table[i, {i, 1, Nnodes}]; (*Nodes numbering*)
Edges = Table[
  Nodes0[[j]] <-> Nodesf[[j]], {j, 1, Nedges}]; (*Edges*)
w={9.59353,17.6205,30.5427,22.4938,20.8078,16.8908,15.662,10.5943}; (*Weights*)
G = Graph[Nodes, Edges, 
  VertexCoordinates -> Table[{x[[i]], y [[i]]}, {i, 1, Nnodes}], 
  VertexShapeFunction -> None] (*Network*)

Can that be done with this example?

Example network

I would recommend using the newer Graph method rather than the older GraphPlot. I've made up some functions for thickness and coloring. You will want to use your own.

  w = {2., 1., 0.5, 0.3, 1.2};
  g = Graph[{1 -> 2, 3 -> 1, 3 -> 2, 4 -> 1, 4 -> 2}];
  styledEdges = MapThread[
   Property[#1, 
     EdgeStyle -> {Hue[LogisticSigmoid[#2]], 
       Thickness[Min[0.03, #2/100]]}] &, {EdgeList[g], w}];
 Graph[styledEdges]
POSTED BY: Seth Chandler
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract