9
$\begingroup$

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.

$\endgroup$
8
  • $\begingroup$ WeightedAdjacencyGraph[Range[11], myAdjacencyMatrix] should do it $\endgroup$ Commented May 19, 2013 at 23:05
  • 7
    $\begingroup$ If you are really working on a tight schedule, I seriously suggest trying with another language. Mathematica has a steep learning curve and isn't appropriate for rush learning $\endgroup$ Commented May 19, 2013 at 23:06
  • 1
    $\begingroup$ How do you want the weights to modify the drawing of the graph? $\endgroup$
    – Szabolcs
    Commented May 19, 2013 at 23:07
  • 5
    $\begingroup$ mmm ... re reading your questions so far, your "tight schedule" seems dangerously near a "homework delivery deadline" $\endgroup$ Commented May 19, 2013 at 23:13
  • 1
    $\begingroup$ @image_doctor: english.stackexchange.com/a/6226/1635 $\endgroup$
    – user484
    Commented Jun 1, 2013 at 21:10

3 Answers 3

12
$\begingroup$

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

$\endgroup$
6
  • 1
    $\begingroup$ To get the "simplified" graph do just myAdjacencyMatrix /. 0 -> Infinity $\endgroup$ Commented May 20, 2013 at 12:43
  • $\begingroup$ @belisarius That works well, thanks! Updated. $\endgroup$
    – cormullion
    Commented May 20, 2013 at 13:00
  • $\begingroup$ Brilliant thankyou. Tried to upvote but wasnt allowed. Is there anyway to move the nodes into a customised format? $\endgroup$ Commented May 20, 2013 at 19:05
  • $\begingroup$ Right-click gives some alternatives, but it's complicated stuff... $\endgroup$
    – cormullion
    Commented May 20, 2013 at 19:16
  • $\begingroup$ @Ryan I don't think you have enough reputation to upvote... $\endgroup$
    – cormullion
    Commented May 20, 2013 at 19:21
4
$\begingroup$

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

$\endgroup$
2
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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