9

I have a weighted adjacency matrix as follows:

myAdjacencyMatrix = {{0, 3, 1, 3, 3, 8, 0, 0, 3, 4},
  {1, 0, 2, 0, 0, 16, 5, 3, 0, 6, 1},
  {2, 3, 0, 0, 1, 1, 4, 1, 1, 0, 0},
  {5, 3, 3, 0, 5, 0, 2, 2, 2, 2, 1},
  {1, 0, 0, 6, 0, 1, 2, 6, 10, 2, 4},
  {0, 11, 3, 0, 1, 0, 8, 3, 1, 3, 3},
  {2, 4, 1, 7, 6, 7, 0, 6, 0, 8, 2},
  {1, 2, 1, 3, 8, 4, 4, 0, 4, 3, 0},
  {0, 0, 0, 1, 4, 1, 3, 4, 0, 6, 4},
  {0, 3, 0, 0, 0, 5, 2, 2, 6, 0, 4},
  {0, 1, 0, 0, 2, 1, 2, 0, 1, 2, 0}}

I want to draw a graph with 11 nodes and the edges weighted as described above. If this is impossible, then I will settle for making a graph with the non-weighted adjacency matrix.

If you could just give me the simple code as I am new to mathematica and am working on a tight schedule.

Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
Ryan Durrant
  • 201
  • 1
  • 2
  • 3

3 Answers3

12

I'm not too good at graphs, but this seems straightforward.

myAdjacencyMatrix =
{{0, 3, 1, 3, 3, 8, 0, 0, 3, 4, 2},
 {1, 0, 2, 0, 0, 16, 5, 3, 0, 6, 1},
 {2, 3, 0, 0, 1, 1, 4, 1, 1, 0, 0},
 {5, 3, 3, 0, 5, 0, 2, 2, 2, 2, 1},
 {1, 0, 0, 6, 0, 1, 2, 6, 10, 2, 4},
 {0, 11, 3, 0, 1, 0, 8, 3, 1, 3, 3},
 {2, 4, 1, 7, 6, 7, 0, 6, 0, 8, 2},
 {1, 2, 1, 3, 8, 4, 4, 0, 4, 3, 0},
 {0, 0, 0, 1, 4, 1, 3, 4, 0, 6, 4},
 {0, 3, 0, 0, 0, 5, 2, 2, 6, 0, 4},
 {0, 1, 0, 0, 2, 1, 2, 0, 1, 2, 0}} /. 0 -> Infinity

(I added an extra 2 to your first row.) Belisarius proposes the 0 -> Infinity to remove 0 weights.

A graph:

g = WeightedAdjacencyGraph[myAdjacencyMatrix, 
     VertexLabels -> "Name",
     EdgeLabels -> "EdgeWeight", 
     EdgeShapeFunction -> f, 
     VertexLabelStyle -> Directive[Red, 18]];

Then an edge function:

f[pts_List, e_] := 
 Block[{s = 0.015, weight = PropertyValue[{g, e}, EdgeWeight]},
  {Arrowheads[{{s, 0.1}, {s, 0.9}}], 
   AbsoluteThickness[weight * 1.5], 
   Arrow[pts]}]

Then draw the graph:

Show[g]

graph

Still looks too messy to be really useful.

By the way, is it correct to make edge rendering function refer to the graph, and the graph function to call the edge rendering function? Seems a bit circular to me...

Update - "Is there anyway to move the nodes?"

I found out that it's straightforward to control the positions of the nodes in advance. You have to create a list of coordinates - in this case 11 are needed - and provide them to the VertexCoordinates option. For example, here is a set of 11 points, arranged in two layers, of four and six points, around a central point:

vertices = 
  Join[
   {{0, 0}},
   Table[{4 Cos[a], 4 Sin[a]}, {a, Pi/4, 2  Pi, Pi/2}],
   Table[{7 Cos[a], 7 Sin[a]}, {a, 0, 5 Pi/3, Pi/3}]
  ];

Then create the graph using the VertexCoordinates -> vertices:

graph moved vertices

cormullion
  • 24,243
  • 4
  • 64
  • 133
3

You can also use the entries of myAdjacencyMatrix directly to set theEdgeStyles:

WeightedAdjacencyGraph[myAdjacencyMatrix /. 0 -> Infinity, 
 GraphLayout -> "RadialEmbedding", 
 EdgeStyle -> {DirectedEdge[i_, j_] :> AbsoluteThickness[ myAdjacencyMatrix[[i, j]]]}]

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
2

With IGraph/M, it's a bit simpler.

myAdjacencyMatrix =
{{0, 3, 1, 3, 3, 8, 0, 0, 3, 4, 2},
 {1, 0, 2, 0, 0, 16, 5, 3, 0, 6, 1},
 {2, 3, 0, 0, 1, 1, 4, 1, 1, 0, 0},
 {5, 3, 3, 0, 5, 0, 2, 2, 2, 2, 1},
 {1, 0, 0, 6, 0, 1, 2, 6, 10, 2, 4},
 {0, 11, 3, 0, 1, 0, 8, 3, 1, 3, 3},
 {2, 4, 1, 7, 6, 7, 0, 6, 0, 8, 2},
 {1, 2, 1, 3, 8, 4, 4, 0, 4, 3, 0},
 {0, 0, 0, 1, 4, 1, 3, 4, 0, 6, 4},
 {0, 3, 0, 0, 0, 5, 2, 2, 6, 0, 4},
 {0, 1, 0, 0, 2, 1, 2, 0, 1, 2, 0}};

IGWeightedAdjacencyGraph[myAdjacencyMatrix,
    GraphLayout -> "CircularEmbedding", EdgeStyle -> Arrowheads[Large],
    ImageSize -> Large] // 
  IGEdgeMap[AbsoluteThickness, EdgeStyle -> IGEdgeProp[EdgeWeight]]

enter image description here

IGWeightedAdjacencyGraph saves you the trouble of having to replace zeros with infinities and IGEdgeMap makes it easy to style based on weight.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263