How to Label Graph Edges with their weights
Asked Answered
C

4

7

Warning! I posted the question when Mathematica v 8.0 was the coolest kid. The bug has been solved as of version 9.0.1

The help for EdgeLabels states:

enter image description here

However:

CompleteGraph[4,
 EdgeWeight -> Range@6,
 VertexShapeFunction -> "Name",
 EdgeLabels -> "EdgeWeight"]

Results in:

enter image description here

So, no Edge Labels ... I guess it is a bug.

I used a nasty construct like:

adj = {{\[Infinity], 1, 1, 1, 1}, {1, \[Infinity], 2, 2, 2}, 
       {1, 2, \[Infinity], 2, 2}, {1, 2, 2, \[Infinity], 2}, 
       {1, 2, 2, 2, \[Infinity]}};

WeightedAdjacencyGraph[adj,
    VertexShapeFunction -> "Name", 
    EdgeLabels -> 
     MapThread[Rule,{EdgeList@#,AbsoluteOptions[#, EdgeWeight]/.{_ -> x_}-> x}], 
    GraphHighlight -> FindEdgeCover[#]]  
                                        &@ WeightedAdjacencyGraph[adj]

enter image description here

Better ideas?

Certainty answered 11/9, 2011 at 20:38 Comment(7)
Have you checked to see if it works using an adjacency matrix with the weights as the numbers in the matrix? I have a notebook (at home I think) that shows how to create weighted graphs with line thicknesses that are proportional to weights - a very popular presentation of data in my field.Peria
Yes, it's at home. I can't help you for another nine hours, sorry :)Peria
@Peria Thanks! I can wait, indeed!Certainty
@belisarius & the four letter word: Graph unfortunately still has some serious problems, be cautious and verify verify verify ... Graph[] objects occasionally end up in a corrupted state causing some functions to either give a wrong result or crash. I've encountered problems with removing vertices and isomorphism testing in particular.Cathrinecathryn
@Cathrinecathryn I seldom use the Graph functionality, and each time I've to navigate trough the complexities of choosing among the disjoint implementations in Mma. I really hope they will get it settled in v9!Certainty
Interestingly, the EdgeLabels doc page on my 8.01/win7-64 version does NOT include the "EdgeWeight" value.Preset
@belisarius Seems like the problem lies with EdgeWeights rather than EdgeLabels. (You may have already realized that. Your MapThread essentially generates weights on-the-fly.)Hallucination
P
9

For a regular GraphPlot, you will need a slightly more complicated solution using EdgeRenderingFunction (documentation). Suppose you have an adjacency matrix where the elements are also the (directional) weights.

lilnums = {{0, 2., 1., 3., 0, 6.}, {0, 0, 1., 2., 0, 0}, {1., 8., 0, 2., 0, 
 2.}, {10., 13., 7., 0, 0, 10.}, {0, 0, 0, 0, 0, 0}, {4., 1., 1., 2.,
 2., 0}}

Here are some labels for the vertices, supposing you are drawing network diagrams for international inter-bank exposures (the original has a lot more countries!).

names = {"AT", "AU", "CA", "CH", "CL", "ES"}

The following does what you need. The tricks are the reference back to the adjacency matrix using the parts of #2 inside the part specification, to reference the correct elements of nums, and the Mean[#1] to locate the label at the midpoint of the edge. The slot #1 seems to hold the coordinates of the vertices.

GraphPlot[lilnums, DirectedEdges -> True, 
 VertexRenderingFunction -> ({White, EdgeForm[Black], Disk[#, .04], 
 Black, Text[names[[#2]], #1]} &), 
 EdgeRenderingFunction -> ({AbsoluteThickness[2], Red, 
 Arrowheads[0.02], Arrow[#1, 0.05], Black, 
 Text[Round@ Abs[(lilnums[[#2[[1]], #2[[2]]]] + 
   lilnums[[#2[[2]], #2[[1]]]])], Mean[#1], 
  Background -> Yellow]} &), VertexLabeling -> True, 
 ImageSize -> 600,  
  PlotLabel -> Style["Plot Label", Bold, 14, FontFamily -> "Arial"]]

enter image description here

Peria answered 12/9, 2011 at 10:25 Comment(4)
(Pedantic point, probably). Am I correct in thinking that for weights greater than 1 this plot contains multiple edge labels (and edges) each placed one-on-top of the other, and it that OK? (It possibly is). For printing purposes, say, will each be rendered in exactly the same place? (I have had similar problems with edge labelling in another field, hence the interest)Stereoscopy
@TomD - I don't think so. The plot is the same if you instead have Sign[lilnums] as the first argument, and/or if the option MultiedgeStyle -> None is used. Timings are the same, too.Peria
@Verbeia. Thanks for the clarification. I missed that point.Stereoscopy
Check chat to see how I did the syntax highlightingPeria
H
5

EdgeLabels -> "EdgeWeight" still doesn't work in 8.0.4 and no longer seems to be in the documentation. However, here is one solution that does work:

lilnums = {{0, 2., 1., 3., 0, 6.}, {0, 0, 1., 2., 0, 0}, {1., 8., 0, 2., 0, 2.},
  {10., 13., 7., 0, 0, 10.}, {0, 0, 0, 0, 0, 0}, {4., 1., 1., 2., 2., 0}}
names = {"AT", "AU", "CA", "CH", "CL", "ES"};
g = WeightedAdjacencyGraph[names, lilnums /. {0 -> \[Infinity]}, 
  VertexShapeFunction -> "Name" , ImagePadding -> 15];
SetProperty[g, EdgeLabels -> MapThread[#1 -> #2 &, 
  {EdgeList[g], PropertyValue[g, EdgeWeight]}]]
Holliman answered 25/2, 2012 at 20:22 Comment(1)
This works just fine. Using the same technique I modified the EdgeStyle so that the lines thickness is proportional to the edge weight. Just set this additional property: EdgeStyle -> MapThread[#1 -> #2 &, {EdgeList[g], AbsoluteThickness[#] & /@ (1 + 3*Rescale[PropertyValue[g, EdgeWeight]])}]Boatwright
H
4

EdgeLabels works fine. EdgeWeights does not.

It may already be obvious from Belisarius' second example that the problem lies with EdgeWeights not EdgeLabels

Here's some additional evidence. EdgeLabels very gladly displays a variety of labels correctly. But when you ask mma to display "EdgeWeights", it incorrectly displays 1's, no matter what you've stored there.

CompleteGraph[4, VertexShapeFunction -> "Name",
 EdgeLabels -> {
   UndirectedEdge[1, 2] -> "hello", 
   UndirectedEdge[1, 4] -> "goodbye", UndirectedEdge[2, 3] -> 55, 
   UndirectedEdge[3, 4] -> \[Pi]/2, 
   UndirectedEdge[4, 2] -> 
   "\!\(\*UnderoverscriptBox[\(\[Sum]\), \(i = 0\), \(26\)]\)(-1\!\(\
   \*SuperscriptBox[\()\), \(i\)]\)\!\(\*SuperscriptBox[\(\[Theta]\), \
   \(n - i\)]\)", UndirectedEdge[1, 3] -> {a, b, c}}]

EdgeWeights.png

The bug is not unique to CompleteGraph. Graph and GridGraph have the same problem.

Hallucination answered 14/9, 2011 at 1:12 Comment(1)
In fact all Graph unctions share the bug. Thanks!Certainty
A
3

The solution is easy. Upgrade to V 8.0.1 :)

At least that is what I have and it works there. (windows 7)

enter image description here

Btw, I do not know if the labels on the edges are correct, but at least it does put them on the figure, unlike your image).

Apatite answered 12/9, 2011 at 6:32 Comment(3)
I get the same output in 8.0.1 on a Mac OS X, but I don't think the weights should be 1 in every case, given the Range construct in his example.Peria
@belisarius This is what I get too, but I agree with Verbeia that the numbers on the edges seem to be incorrect.Preset
@Apatite Very strange indeed! EdgeWeights do not display properly for Graph either (in 8.0.1). Try: Graph[{1 \[UndirectedEdge] 2, 2 \[UndirectedEdge] 3, 3 \[UndirectedEdge] 1}, EdgeWeight -> {2, 3, 4}, EdgeLabels -> "EdgeWeight"]Hallucination

© 2022 - 2024 — McMap. All rights reserved.