Message Boards Message Boards

1
|
8167 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

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

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

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