8

I would like to draw a Graph with defined $x$ coordinates and variable node sizes. If I simply replace the $x$ coordinates of a graph, then nodes can overlap and edges may cross each other. I would appreciate any help pointing me in the right direction on how to go about setting the $Y$ coordinates, or alternative approaches to plotting, such that the nodes are nicely spaced out and, as far as possible, edges don't cross.

(*egdata*)    
relationships = 
 {1 <-> 2, 2 <-> 3, 2 <-> 4, 2 <-> 6, 3 <-> 5, 6 <-> 7,4 <-> 8, 4 <-> 9};
numNodes = 
 Max[relationships[[All, 2]]];
sizes = RandomReal[{0.25, 1}, numNodes];
xCoords = {0, 1, 2, 2, 3, 3, 4, 5, 5};

I would like to be able to automatically generate a plot similar to this (without having to manually specify $Y$ coordinates.):

Graph[
 relationships, VertexSize -> Thread[Range[numNodes] -> sizes], 
 VertexCoordinates -> 
  Transpose[{xCoords,(*yCoords*){1, 1, 1, 3, 2, 1, 2, 3, 4}}]]

Using VertexCoordinateRules with GraphPlot is the best I can do, but doesn't solve the problem:

relationships = 
 {1 -> 2, 2 -> 3, 2 -> 4, 2 -> 6, 3 -> 5, 6 -> 7, 4 -> 8, 4 -> 9};
xCoords = 
 {0, 1, 2, 2, 3, 3, 4, 5, 5};
numNodes = 
 Max[relationships[[All, 2]]];
sizes = RandomReal[{0.25, 1}, numNodes];
GraphPlot[
 relationships,
 VertexCoordinateRules -> 
  Thread[
   Range[numNodes] -> 
   Transpose[{xCoords, Table[Automatic, {numNodes}]}]],   
 VertexRenderingFunction -> ({White, EdgeForm[Black], Disk[#, .3], 
  Black, Text[#2, #1]} &)
]

Thanks in advance!

Daniel S
  • 233
  • 1
  • 8
  • Although this doesn't solve the stated problem ,TreePlot[relationships, Left] looks like it may be useful to you. – 2012rcampion Mar 17 '15 at 14:21
  • 1
    Ignore explicit values of y coordinate first, and instead just track order of nodes/edges (along y axis) on every value of x with a node. Construct set of simple constraining inequalities (joining edge y values need to be equal, non-joining unequal, and no pair of edges must change order in their x interval intersections) to be reduced (or for decision of graph planarity). After this edges are guaranteed to be conceptually non-intersecting, and values of y can be computed on basis of sizes of nodes. Well, this is easier said than done, but I believe that's the most practical approach. – kirma Apr 17 '15 at 20:38

1 Answers1

4

not quite what you asked for, but possibly useful:

relationships = {1 <-> 2, 2 <-> 3, 2 <-> 4, 3 <-> 5, 2 <-> 6, 6 <-> 7,
  4 <-> 8, 4 <-> 9};
numNodes = Max[relationships[[All, 2]]];
sizes = RandomReal[{0.25, 1}, numNodes];
xCoords = {0, 1, 2, 2, 3, 3, 4, 5, 5};
vars0 = Array[a, 9];
Manipulate[
    vars = {a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]};
    p = Graph[relationships, 
    VertexSize -> Thread[Range[numNodes] -> sizes], 
    VertexCoordinates -> Transpose[{xCoords, vars}], 
    VertexLabels -> "Name"] , 
  Evaluate[Sequence @@ 
      Table[{{vars0[[i]], i}, 1, Length@vars0, .1}, {i, Length@vars0}]], 
      TrackedSymbols -> All]

enter image description here

or maybe better using Locator:

 relationships = {1 <-> 2, 2 <-> 3, 2 <-> 4, 3 <-> 5, 2 <-> 6, 6 <-> 7,
        4 <-> 8, 4 <-> 9};
 numNodes = Max[relationships[[All, 2]]];
 v0 = VertexCoordinateRules /.
     First@Cases[GraphPlot[Graph[relationships]], _Rule, Infinity];
 Manipulate[Graph[relationships, VertexCoordinates -> vtx],
         {{vtx, v0}, Locator, Appearance -> None}]
george2079
  • 38,913
  • 1
  • 43
  • 110
  • Thanks George. Unfortunately, my actual data has hundreds of nodes, so manually setting the coordinates, even in a manipulate, isn't a viable solution. – Daniel S Apr 23 '15 at 13:19