3
$\begingroup$

If one creates a graph with two edges between the same two vertices, WL draws them in a default coordinate space in which the two edges that pass-through coordinate positions that are placed on curved lives that deviate from the straight line between the vertices. Hence, one might expect that there is a way to control the path of the edges connecting the vertices, at least internally, from the automatic default display of an edge as a straight line between the vertices to a curved path. If so, one might be able to control the edge to "bend" in a right angle. However, from the documentation it is not clear how this might be done.

Likewise, can try to "hide" a vertex between two other vertices to achieve the same effect at the cost of having "hidden" vertices. It would seem one might at least be able to specify the style of the vertex to simply appear as a single pixel or close enough to it that might make the vertex seem hidden by making its absolute size very small. Although one can specify a VertexLabel, as say 3->"" to display without a label, I have been unable to figure out how to control the size of one vertex without affecting the size of the other vertices, even though I try to specify the VertexStyle of each separately.

With respect to the second issue, the following code in WL12.3 fails to achieve making vertex 3 minute so that it is in effect hidden.

familytreegraph = Graph[{1 \[UndirectedEdge] 3, 2 \[UndirectedEdge] 3, 
3 \[UndirectedEdge] 4, 3 \[UndirectedEdge] 5, 
3 \[UndirectedEdge] 6, 3 \[UndirectedEdge] 7, 
3 \[UndirectedEdge] 8}, 
VertexLabels -> {1 -> "Jakob - Father", 2 -> "Anna - Mother", 
 3 -> "", 4 -> "Jeno", 5 -> "Ilona", 6 -> "Flora", 
7 -> "George Polya", 8 -> "Laslo"}, EdgeStyle -> Black,
VertexStyle -> {1 -> LightBlue}, VertexSize -> {1 -> {.03, .03}}, 
VertexStyle -> {2 -> LightBlue}, VertexSize -> {2 -> {.03, .03}}, 
VertexStyle -> {3 -> Black}, VertexSize -> {3 -> {.0001, .0001}}, 
VertexStyle -> {4 -> LightBlue}, VertexSize -> {4 -> {.03, .03}}, 
VertexStyle -> {5 -> LightBlue}, VertexSize -> {5 -> {.03, .03}}, 
VertexStyle -> {6 -> LightBlue}, VertexSize -> {6 > {.03, .03}}, 
VertexStyle -> {7 -> LightBlue}, VertexSize -> {7 -> {.03, .03}}, 
VertexStyle -> {8 -> LightBlue}, VertexSize -> {8 -> {.03, .03}}, 
VertexCoordinates -> {1 -> {0, 1}, 2 -> {1, 1}, 3 -> {.5, .5}, 
4 -> {0, 0}, 5 -> {.25, 0}, 6 -> {.5, 0}, 7 -> {.75, 0}, 
8 -> {1, 0}}] 

enter image description here Note that the size of vertices 2 and 4-8 are specifically sized the same as vertex 1, but do not display at the same size as vertex 1 but rather at the size of vertex 3, the vertex I am trying to "hide".

Is there a way to "hide" vertex 3, properly size all the vertices, as well as manipulate the curvature of the edges connecting vertices 1 and 2 to vertex 3 so that the graph reflects a more classical depiction of a family tree?

Keep in mind that the final object desired is a graph that potentially can be analyzed as a subgraph of a larger graph and that can take advantage of other graph properties and not simply a graphic object such as Dendrogram that do not inherit the properties of a graph, even though their rendered shape is similar to the hierarchical effect that is sought here.

$\endgroup$
1
  • 1
    $\begingroup$ You cannot use the same option (VertexSize) multiple times because it takes into account only the first use of it. Instead, provide a list: VertexSize -> {1 -> {.03, .03}, 2 -> {.03, .03}, 3 -> {.0001, .0001}, ...}. You can also provide the size of only one vertex: VertexSize -> {3 -> {.0001, .0001}}. $\endgroup$
    – Domen
    Oct 2 at 9:15
9
$\begingroup$
edgelist = {1 <-> 3, 2 <-> 3, 3 <-> 4, 3 <-> 5, 3 <-> 6, 3 <-> 7, 3 <-> 8};

vertexlabels = {1 -> "Jakob - Father", 2 -> "Anna - Mother", 4 -> "Jeno",
  5 -> "Ilona", 6 -> "Flora", 7 -> "George Polya", 8 -> "Laslo"};

vcoords = {1 -> {0, 1}, 2 -> {1, 1}, 3 -> {.5, .5}, 4 -> {0, 0}, 
   5 -> {.25, 0}, 6 -> {.5, 0}, 7 -> {.75, 0}, 8 -> {1, 0}};

options = {VertexLabels -> vertexlabels, 
   EdgeStyle -> Black, 
   VertexStyle -> {_ -> LightBlue, 3 -> Black}, 
   VertexSize -> {_ -> {.03, .03}, 3 -> 0}, 
   ImagePadding -> {{5, 70}, {5, 40}}, 
   PerformanceGoal -> "Quality", 
   ImageSize -> Large, 
   VertexCoordinates -> vcoords};

Graph[edgelist, options]

enter image description here

Using a built-in (but undocumented) EdgeShapeFunction "CurvedArc":

Graph[edgelist, options, 
 EdgeShapeFunction -> 
  (GraphElementData["CurvedArc", "Curvature" -> (-2 Subtract @@ #[[{1, -1}, 1]])][##]&)]

enter image description here

A variation:

Graph[edgelist, 
 VertexLabels -> MapAt[Placed[#, Below] &, vertexlabels, {All, 2} ], 
 options, 
 EdgeShapeFunction -> {_ -> (GraphElementData["CurvedArc", 
        "Curvature" -> (-2 Subtract @@ #[[{1, -1}, 1]])][##] &), 
   UndirectedEdge[1 | 2, _] -> (GraphElementData["CurvedArc", 
        "Curvature" -> (-9 Subtract @@ #[[{1, -1}, 1]])][##] &)}]

enter image description here

We can also use a custom EdgeShapeFunction to make the graph look like a family tree:

ClearAll[zigZag]
zigZag[{{a_, b_}, {c_, d_}}, ___] := Line@{{a, b}, If[b <= d, {a, d}, {c, b}], {c, d}}

Graph[edgelist, options, EdgeShapeFunction -> zigZag]

enter image description here

An alternative approach using BezierCurve:

ClearAll[bezierEdge]
bezierEdge[w_: 1/3] := BezierCurve[{#[[1]], 
     {#[[1, 1]], (w #[[1, 2]] + (1 - w) #[[2, 2]])}, 
     {#[[2, 1]], ((1 - w) #[[1, 2]] + w #[[2, 2]])}, #[[2]]}] &

Graph[edgelist, options, EdgeShapeFunction -> bezierEdge[]]

enter image description here

A generalization that gives spline curves controlled by two parameters:

ClearAll[bSplineEdge]
bSplineEdge[w_: Automatic, sw_: Automatic] := 
 Module[{vc = SortBy[Last]@#, q = w /. Automatic -> 0}, 
   BSplineCurve[{vc[[1]], {vc[[1, 1]], q vc[[1, 2]] + (1 - q) vc[[2, 2]]}, vc[[2]]}, 
    SplineWeights -> {1, sw /. Automatic -> 10^3, 1}]] &

Examples:

Multicolumn[Graph[edgelist, options,
    EdgeShapeFunction -> ToExpression[#], 
    PlotLabel -> Style[#, 16, Black]] & /@ 
  {"bSplineEdge[]", "bSplineEdge[1/10,1]", "bSplineEdge[1/2]", "bSplineEdge[.9]"}, 
 2]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.