# How to set the Y coordinates for a Graph with defined X coordinates to prevent overlap of nodes?

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 ->
Range[numNodes] ->
Transpose[{xCoords, Table[Automatic, {numNodes}]}]],
VertexRenderingFunction -> ({White, EdgeForm[Black], Disk[#, .3],
Black, Text[#2, #1]} &)
]


• Although this doesn't solve the stated problem ,TreePlot[relationships, Left] looks like it may be useful to you. Mar 17, 2015 at 14:21
• 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. Apr 17, 2015 at 20:38

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]


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}]

• Thanks George. Unfortunately, my actual data has hundreds of nodes, so manually setting the coordinates, even in a manipulate, isn't a viable solution. Apr 23, 2015 at 13:19