6
$\begingroup$

I have a relatively large set of data that I am trying to turn into a weighted, directed graph. The data concerns the inflow of migrants based on country of origin. I currently have three columns of data in excel: a number representing country migrated to ($a_i$), a number representing country of origin ($b_i$), and the number of migrants, $n$, who have traveled from $b_i$ to $a_i$.

If I turn this data into a set of ordered triples ($b_i$,$a_i$,$\sigma$) where $a_i$ and $b_i$ are as defined above, and $\sigma$ represents some sort of weight (which I will calculate based upon $n$), would it be possible to have mathematica interpret these triples as directions for constructing a graph? That is, could I somehow yield a directed graph such that each triple corresponds to an edge $b_i\rightarrow a_i$ with weight $\sigma$? Any help is appreciated.

$\endgroup$
3
  • $\begingroup$ Sure; look up DirectedEdge[] and the EdgeWeight option of Graph[]. If you want a demo of how you can use these; please include a (small) example. $\endgroup$ Commented Oct 10, 2012 at 13:59
  • 1
    $\begingroup$ Half the work is importing the data. You merely need to import the Excel file as a list through something like dataFile = Import["T10.xls"] I suggest working first with a small number of records till you get a feel for how the data are organized. $\endgroup$
    – DavidC
    Commented Oct 10, 2012 at 14:20
  • $\begingroup$ Does inflow exist between every possible pair of countries? In other words do you have a complete weighted graph? $\endgroup$ Commented Oct 10, 2012 at 14:26

1 Answer 1

6
$\begingroup$

I will assume the following:

  1. If inflow is zero between some countries - there is no edge between them
  2. Inflow can be non-zero even between non-bordering countries

I will try to simulate your data - to get something that reminiscent of numbers after the import from Excel. Consider South America:

countries = CountryData["SouthAmerica"]; countries // Length

14

This will simulate your data

directions = Union@Table[{countries[[Mod[k, 14] + 1]], 
     RandomChoice[DeleteCases[countries, countries[[Mod[k, 14] + 1]]]]}, {k, 1, 20}];

flows = DirectedEdge @@@ directions;

data = Transpose[Append[Transpose[#], RandomReal[1, Length[#]]] &@directions];

Grid[data, Frame -> All, Alignment -> Left]

enter image description here

An obvious thing to do is to plot this graph in a geographical layout of the countries. The lighter the color of the edge, the greater is the inflow. I also color countries according to population:

Show[
 Graphics[{EdgeForm[GrayLevel[.6]], Opacity[.5], 
     ColorData["TemperatureMap"][
      CountryData[#, "Population"]/1.95423`*^8], 
     CountryData[#, "Polygon"]} & /@ CountryData["SouthAmerica"]],
 Graph[
  countries,
  flows,
  EdgeWeight -> data[[All, 3]],
  EdgeStyle -> 
   MapThread[
    Rule, {flows, 
     Directive[ColorData["SolarColors"][#], Thickness[.01]] & /@ 
      data[[All, 3]]}],
  VertexLabels -> "Name",
  VertexCoordinates -> (Reverse[
       CountryData[#, "CenterCoordinates"]] & /@ 
     CountryData["SouthAmerica"]),
  EdgeShapeFunction -> 
   GraphElementData[{"FilledArrow", "ArrowSize" -> .035}]
  ]
 ]

enter image description here

You may also try other layouts - coming from graph properties:

Graph[
   countries,
   flows,
   EdgeWeight -> data[[All, 3]],
   EdgeStyle -> 
    MapThread[
     Rule, {flows, 
      Directive[ColorData["SolarColors"][#], Thickness[.01]] & /@ 
       data[[All, 3]]}],
   VertexLabels -> "Name",
   EdgeShapeFunction -> 
    GraphElementData[{"FilledArrow", "ArrowSize" -> .035}],
   GraphLayout -> #,
   ImagePadding -> 40] & /@ 
     {"CircularEmbedding", "SpringElectricalEmbedding"}//Row

enter image description here

$\endgroup$
1
  • $\begingroup$ Beautiful answer, thanks so much. $\endgroup$
    – Steve W
    Commented Oct 12, 2012 at 1:05

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.