How to get graph layout that reflects edge weights?

Update: Since version 9, weighted layouts are available. See this answer.


The short answer is, unfortunately no, in version 8.0.* at least, the built-in layout algorithms do not take edge weight into account. Consider a version of your example:

Unweighted

adjMat1 = {{Infinity, 1, 1, 1, 1}, {1, Infinity, 1, 1, 1}, {1, 1, 
    Infinity, 1, 1}, {1, 1, 1, Infinity, 1}, {1, 1, 1, 1, Infinity}};

Weighted

adjMat2 = {{Infinity, 8, 6, 3, 7}, {1, Infinity, 1, 1, 1}, {2, 5, 
    Infinity, 9, 4}, {1, 1, 1, Infinity, 1}, {1, 1, 1, 1, Infinity}};

Weighted adjacency matrix converted to multiedge rule form

multiedge = DeleteCases[ Flatten@Table[
    If[i == j, Null, Table[i -> j, {adjMat2[[i, j]]}]], {i, 
     Length[adjMat2]}, {j, Length@First@adjMat2}], Null]

(* Output:   {1 -> 2, 1 -> 2, 1 -> 2, 1 -> 2, 1 -> 2, 1 -> 2, 1 -> 2, 1 -> 2, 
 1 -> 3, 1 -> 3, 1 -> 3, 1 -> 3, 1 -> 3, 1 -> 3, 1 -> 4, 1 -> 4, 
 1 -> 4, 1 -> 5, 1 -> 5, 1 -> 5, 1 -> 5, 1 -> 5, 1 -> 5, 1 -> 5, 
 2 -> 1, 2 -> 3, 2 -> 4, 2 -> 5, 3 -> 1, 3 -> 1, 3 -> 2, 3 -> 2, 
 3 -> 2, 3 -> 2, 3 -> 2, 3 -> 4, 3 -> 4, 3 -> 4, 3 -> 4, 3 -> 4, 
 3 -> 4, 3 -> 4, 3 -> 4, 3 -> 4, 3 -> 5, 3 -> 5, 3 -> 5, 3 -> 5, 
 4 -> 1, 4 -> 2, 4 -> 3, 4 -> 5, 5 -> 1, 5 -> 2, 5 -> 3, 5 -> 4} *)

This shows that any of the three plotting methods give essentially the same layout for the same layout (Method/GraphLayout) option.

Manipulate[
 Row[{GraphPlot[multiedge, MultiedgeStyle -> None, Method -> s], 
   GraphPlot[adjMat1, MultiedgeStyle -> None, Method -> s], 
   AdjacencyGraph[adjMat1 /. \[Infinity] -> 0, 
    GraphLayout -> s]}], {s, {"SpringElectricalEmbedding", 
   "SpringEmbedding", "HighDimensionalEmbedding", "CircularEmbedding",
    "RandomEmbedding", "LinearEmbedding"}}]

enter image description here

If you were to come up with your own algorithm for allowing for the weights, you could draw graphs using that algorithm using the VertexCoordinateRules option.

There is a Weighted option in the GraphUtilities package, but it doesn't apply to visualisation.


Here's a way to represent the weights of the edges, first using GraphPlotand then Graph.

First, let's grab the edge weights from PlatoManiac's code and format them suitably for GraphPlot. (We'll use the unrasterized values.):

gr = WeightedAdjacencyGraph[adjMat2, DirectedEdges -> True];
weight = AbsoluteOptions[gr, EdgeWeight][[1, 2]];
edge = EdgeList@gr;
k = Graph[edge, EdgeLabels -> (el=MapThread[#1 -> #2 &, {edge, weight}])];
g = (AbsoluteOptions[k, 
  EdgeLabels] /. {(a_ \[DirectedEdge] b_ -> c_) :>  {a -> b, 
    c}})[[1, 2]];

GraphPlot

Now, making use of a technique illustrated here, let's make the thickness of the edges reflect the weights:

GraphPlot[g, 
   EdgeRenderingFunction -> ({Text[Style[#3, 15], Mean[#1]], Blue, 
   AbsoluteThickness[0.5 + #3/5], Arrowheads[0.02 + #3/170], 
   Arrow[#1, 0.075]} &), VertexLabeling -> True]

weighted graph


Graph

{e, w} = Transpose[g]
Graph[e, EdgeWeight -> w, 
EdgeLabelStyle -> Directive[Red, 20, Background -> White], 
EdgeLabels -> el , 
EdgeShapeFunction -> 
   el /. {((a_ \[DirectedEdge] b_) ->  c_) -> ((a \[DirectedEdge] 
    b) -> ({AbsoluteThickness[.9 + c/4], Arrow[#1, 0.025]} &))}]

graph 2


Here is what you can do

Options[VisualizeNetwork] = Options[Graph];
VisualizeNetwork[{adjMat2_, edgecoloring_: {Green, Red}, 
scaling_: 600, opacity_: 0.5, ShowEdgeWeight_: True}, 
opts : OptionsPattern[]] :=
Block[{gr, weight, Nweight, edge, nodes, vertexStyle, EdgeBlendColor,edgeStyle, g},
gr = WeightedAdjacencyGraph[adjMat2, DirectedEdges -> True];
(*Lets extract the edge weight list from your graph object*)
weight = AbsoluteOptions[gr, EdgeWeight][[1, 2]];
(*Extract the edge list*)
edge = EdgeList@gr;
(*Extract the vertex list*)
nodes = VertexList@gr;
(* Make a color blend by scaling all the edge weight with the maximum edge weight *)
EdgeBlendColor = Map[ Blend[edgecoloring, #/Max[weight]] &, weight];
(* Make a thickness by scaling all the edge weight with the maximum edge weight *)
edgeStyle = 
MapThread[(#1 -> {Opacity[opacity], #3, 
     Thickness[#2/scaling]}) &, {edge, weight, EdgeBlendColor}];
Nweight = MapThread[
 Rasterize[#1, ImageSize -> 9, 
   Background -> Lighter@#2] &, {weight, EdgeBlendColor}];
 g = If[ShowEdgeWeight == True,
 Graph[nodes, edge, EdgeStyle -> edgeStyle, 
  EdgeLabels -> Flatten@MapThread[#1 -> #2 &, {edge, Nweight}], 
  VertexLabels -> 
   Table[i -> Placed["Name", {1/2, 1/2}], {i, nodes}], opts], 
 Graph[nodes, edge, EdgeStyle -> edgeStyle, 
  VertexLabels -> 
   Table[i -> Placed["Name", {1/2, 1/2}], {i, nodes}], opts]
 ];
g
];

You can call the function with all options available to Graph object and it returns a Mathematica 8.0 Graph object.Hence you don't need to call GraphPlot to tweak the visualization the default Graph object comes with this lay out where edge weight is evidently visible.

Given a weighted adjacency matrix it gives you the graph where you now see the edge weight in the lay out. We use color blend for edge color and control the edge thickness by scaling the all the edge weights by their maximum. There is also a True or False choice to show the edge weights explicitly or not.

adjMat1 = {{Infinity, 1, 1, 1, 1}, {1, Infinity, 1, 1, 1}, {1, 1, 
Infinity, 1, 1}, {1, 1, 1, Infinity, 1}, {1, 1, 1, 1, Infinity}};
adjMat2 = {{Infinity, 8, 6, 3, 7}, {1, Infinity, 1, 1, 1},
{2, 5,Infinity, 9, 4}, {1, 1, 1, Infinity, 1}, {1, 1, 1, 1, Infinity}};
(* Some Graph visualization option *)
opts = {VertexSize -> Medium, VertexSize -> Medium,
VertexStyle ->Directive[Opacity[0.65`], Blue, EdgeForm[None]], 
VertexLabelStyle -> Directive[GrayLevel[0], 12], 
VertexSize -> {"Scaled", 0.3`}, 
GraphLayout -> "SpringElectricalEmbedding"};
(* Call the function *)
GraphicsGrid@{{VisualizeNetwork[{adjMat1, {Yellow, Red}, 600, 0.5, 
 True}, opts], 
VisualizeNetwork[{adjMat2, {Yellow, Red}, 600, 0.5, True}, opts]}}

enter image description here