Problems positioning nodes in a family tree with DOT

I’m trying to use GraphViz to typeset a family tree, largely building off of this Python script and this StackOverflow thread. I can make a decent-looking graph going back through grandparents and including siblings, like so:

digraph {
    splines = ortho;
    node [shape=box]
    edge [dir=none]

    SMITH_BRIDGET [label="Bridget Smith", style=filled, fillcolor=bisque];
    SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];

    SMITH_BERTRAND [label="Bertrand Smith", style=filled, fillcolor=azure2];
    JOHNSON_BEATRICE [label="Beatrice Johnson", style=filled, fillcolor=bisque];

    JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
    JONES_HENRY_JR [label="Henry Jones Junior", style=filled, fillcolor=azure2];
    JONES_DIANA [label="Diana Jones", style=filled, fillcolor=bisque];

    JONES_HENRY [label="Henry Jones", style=filled, fillcolor=azure2];
    ADAMS_ABIGAIL [label="Abigail Adams", style=filled, fillcolor=bisque];

    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];

    {
        rank=same;
        F1_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_BERTRAND -> F1_top
        F1_top -> JOHNSON_BEATRICE
    }
    {
        rank=same;
        F1_0 [shape=circle, label="", height=0.01, width=0.01];
        F1_1 [shape=circle, label="", height=0.01, width=0.01];
        F1_2 [shape=circle, label="", height=0.01, width=0.01];
        F1_0 -> F1_1 -> F1_2;
    }
    F1_top -> F1_1;
    F1_0 -> SMITH_BRIDGET;
    F1_2 -> SMITH_ADAM;

    {
        rank=same;
        F2_top [shape=circle, label="", height=0.01, width=0.01];
        JONES_HENRY -> F2_top
        F2_top -> ADAMS_ABIGAIL
    }
    {
        rank=same;
        F2_0 [shape=circle, label="", height=0.01, width=0.01];
        F2_1 [shape=circle, label="", height=0.01, width=0.01];
        F2_2 [shape=circle, label="", height=0.01, width=0.01];
        F2_0 -> F2_1 -> F2_2;
    }
    F2_top -> F2_1;
    F2_0 -> JONES_MARY;
    F2_1 -> JONES_HENRY_JR;
    F2_2 -> JONES_DIANA;

    {
        rank=same;
        F3_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_ADAM -> F3_top
        F3_top -> JONES_MARY
    }
    {
        rank=same;
        F3_0 [shape=circle, label="", height=0.01, width=0.01];
        F3_1 [shape=circle, label="", height=0.01, width=0.01];
        F3_2 [shape=circle, label="", height=0.01, width=0.01];
        F3_0 -> F3_1 -> F3_2;
    }
    F3_top -> F3_1;
    F3_0 -> SMITH_JOHN;
    F3_2 -> SMITH_JANE;
}

I thought I had a grip on how the person nodes need to be ordered to produce my desired output, but when I add in great-grandparents, things go kaflooey:

digraph {
    splines = ortho;
    node [shape=box]
    edge [dir=none]

    SMITH_BRIDGET [label="Bridget Smith", style=filled, fillcolor=bisque];
    SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];

    SMITH_BERTRAND [label="Bertrand Smith", style=filled, fillcolor=azure2];
    JOHNSON_BEATRICE [label="Beatrice Johnson", style=filled, fillcolor=bisque];

    NEWTON_CHARLOTTE [label="Charlotte Newton", style=filled, fillcolor=bisque];
    SMITH_CHARLES [label="Charles Smith", style=filled, fillcolor=azure2];

    JOHNSON_BAINES [label="Baines Johnson", style=filled, fillcolor=azure2];
    MAXWELL_MARGARET [label="Margaret Maxwell", style=filled, fillcolor=bisque];

    JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
    JONES_HENRY_JR [label="Henry Jones Junior", style=filled, fillcolor=azure2];
    JONES_DIANA [label="Diana Jones", style=filled, fillcolor=bisque];

    JONES_HENRY [label="Henry Jones", style=filled, fillcolor=azure2];
    ADAMS_ABIGAIL [label="Abigail Adams", style=filled, fillcolor=bisque];

    JONES_JEREMIAH [label="Jeremiah Jones", style=filled, fillcolor=azure2];
    PLANK_PATRICIA [label="Patricia Plank", style=filled, fillcolor=bisque];

    ADAMS_DOUGLAS [label="Douglas Adams", style=filled, fillcolor=azure2];
    DENT_URSULA [label="Ursula Dent", style=filled, fillcolor=bisque];

    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];

    {
        rank=same;
        F1_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_BERTRAND -> F1_top
        F1_top -> JOHNSON_BEATRICE
    }
    {
        rank=same;
        F1_0 [shape=circle, label="", height=0.01, width=0.01];
        F1_1 [shape=circle, label="", height=0.01, width=0.01];
        F1_2 [shape=circle, label="", height=0.01, width=0.01];
        F1_0 -> F1_1 -> F1_2;
    }
    F1_top -> F1_1;
    F1_0 -> SMITH_BRIDGET;
    F1_2 -> SMITH_ADAM;

    {
        rank=same;
        F2_top [shape=circle, label="", height=0.01, width=0.01];
        JONES_HENRY -> F2_top
        F2_top -> ADAMS_ABIGAIL
    }
    {
        rank=same;
        F2_0 [shape=circle, label="", height=0.01, width=0.01];
        F2_1 [shape=circle, label="", height=0.01, width=0.01];
        F2_2 [shape=circle, label="", height=0.01, width=0.01];
        F2_0 -> F2_1 -> F2_2;
    }
    F2_top -> F2_1;
    F2_0 -> JONES_MARY;
    F2_1 -> JONES_HENRY_JR;
    F2_2 -> JONES_DIANA;

    {
        rank=same;
        F3_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_ADAM -> F3_top
        F3_top -> JONES_MARY
    }
    {
        rank=same;
        F3_0 [shape=circle, label="", height=0.01, width=0.01];
        F3_1 [shape=circle, label="", height=0.01, width=0.01];
        F3_2 [shape=circle, label="", height=0.01, width=0.01];
        F3_0 -> F3_1 -> F3_2;
    }
    F3_top -> F3_1;
    F3_0 -> SMITH_JOHN;
    F3_2 -> SMITH_JANE;

    {
        rank=same;
        F4_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_CHARLES -> F4_top
        F4_top -> NEWTON_CHARLOTTE
    }
    {
        rank=same;
        F4_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F4_top -> F4_0;
    F4_0 -> SMITH_BERTRAND;

    {
        rank=same;
        F5_top [shape=circle, label="", height=0.01, width=0.01];
        JOHNSON_BAINES -> F5_top
        F5_top -> MAXWELL_MARGARET
    }
    {
        rank=same;
        F5_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F5_top -> F5_0;
    F5_0 -> JOHNSON_BEATRICE;

    {
        rank=same;
        F6_top [shape=circle, label="", height=0.01, width=0.01];
        JONES_JEREMIAH -> F6_top
        F6_top -> PLANK_PATRICIA
    }
    {
        rank=same;
        F6_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F6_top -> F6_0;
    F6_0 -> JONES_HENRY;

    {
        rank=same;
        F7_top [shape=circle, label="", height=0.01, width=0.01];
        ADAMS_DOUGLAS -> F7_top
        F7_top -> DENT_URSULA
    }
    {
        rank=same;
        F7_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F7_top -> F7_0;
    F7_0 -> ADAMS_ABIGAIL;
}

As you can see if you render this, great-grandfather Charles Smith, rather than being placed to the left of his beloved Charlotte Newton, has been moved two blocks over to the right and stuck in between Baines Johnson and Margaret Maxwell (the scandal!). I’ve tried reordering the person nodes at the top of the file in various ways, but they’ve all either made no difference or else made things worse. In addition, I can’t even figure out if the order of the “family blocks” makes a difference here.

I found this forum post that seemed to be dealing with the same problem, but following the advice there of setting remincross = true and using -Gmclimit=10 made no difference to the output.

So, how do I get the second family tree to look “proper,” and what rules regarding node order must I follow when creating similar family trees of arbitrary size?

None of the Graphviz programs are well suited for family trees.
If you want to persevere, maybe the following will help. It uses clusters to collect “parental units”.
But note that things will probably go south if a “parental unit” includes more than 3.
I got confused by the relationships, so the following is only partially complete.

graph {
    splines = ortho;
    //splines=false
    nodesep=.5
    node [shape=box]
    edge [dir=none]
    
subgraph clusterA{
    peripheries=0
    SMITH_BRIDGET [label="Bridget Smith", style=filled, fillcolor=bisque];
    SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];
    connectA1 [shape=point]
    edge [minlen=0]
    SMITH_BRIDGET -- connectA1 -- SMITH_ADAM  [minlen=0]
}

subgraph clusterB{
    peripheries=0
    SMITH_BERTRAND [label="Bertrand Smith", style=filled, fillcolor=azure2];
    JOHNSON_BEATRICE [label="Beatrice Johnson", style=filled, fillcolor=bisque];
    connectB1 [shape=point]
    edge [minlen=0]
    SMITH_BERTRAND  -- connectB1 -- JOHNSON_BEATRICE
}

subgraph clusterC{
    peripheries=0
    NEWTON_CHARLOTTE [label="Charlotte Newton", style=filled, fillcolor=bisque];
    SMITH_CHARLES [label="Charles Smith", style=filled, fillcolor=azure2];
    connectC1 [shape=point]
    edge [minlen=0]
    NEWTON_CHARLOTTE -- connectC1 -- SMITH_CHARLES
}

subgraph clusterD{
    peripheries=0
    JOHNSON_BAINES [label="Baines Johnson", style=filled, fillcolor=azure2];
    MAXWELL_MARGARET [label="Margaret Maxwell", style=filled, fillcolor=bisque];
    connectD1 [shape=point]
    edge [minlen=0]
    JOHNSON_BAINES -- connectD1 --  MAXWELL_MARGARET
}

subgraph clusterE{
    peripheries=0
    JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
    JONES_HENRY_JR [label="Henry Jones Junior", style=filled, fillcolor=azure2];
    JONES_DIANA [label="Diana Jones", style=filled, fillcolor=bisque];
    connectE1 [shape=point]
    connectE2 [shape=point]
    edge [minlen=0]
    JONES_MARY -- connectE1 --  JONES_HENRY_JR -- connectE2 -- JONES_DIANA
}

subgraph clusterF{
    peripheries=0
    JONES_HENRY [label="Henry Jones", style=filled, fillcolor=azure2];
    ADAMS_ABIGAIL [label="Abigail Adams", style=filled, fillcolor=bisque];
    connectF1 [shape=point]
    edge [minlen=0]
    JONES_HENRY -- connectF1 --  ADAMS_ABIGAIL
}

subgraph clusterG{
    peripheries=0
    JONES_JEREMIAH [label="Jeremiah Jones", style=filled, fillcolor=azure2];
    PLANK_PATRICIA [label="Patricia Plank", style=filled, fillcolor=bisque];
    connectG1 [shape=point]
    edge [minlen=0]
    JONES_JEREMIAH -- connectG1 --  PLANK_PATRICIA
}

subgraph clusterH{
    peripheries=0
    ADAMS_DOUGLAS [label="Douglas Adams", style=filled, fillcolor=azure2];
    DENT_URSULA [label="Ursula Dent", style=filled, fillcolor=bisque];
    connectH1 [shape=point]
    edge [minlen=0]
    ADAMS_DOUGLAS -- connectH1 -- DENT_URSULA 
}

subgraph clusterI{
    peripheries=0
    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];
    connectI1 [shape=point]
    edge [minlen=0]
    SMITH_JOHN -- connectI1 -- SMITH_JANE 
}

edge [minlen=1]
connectH1 -- ADAMS_ABIGAIL
connectG1 --  JONES_HENRY 
}

Giving:

That basically appears to be the same approach I’m taking already. If you’re suggesting something that I’m not already doing, I’m not seeing it.

The difference is using clusters. Every node in a cluster will be positioned near each other.
If you change peripheries=0 to peripheries=1 (or XXperipheries=0, you will see the boundaries of the clusters

Am I not already using “clusters” with code like this?

    {
        rank=same;
        F4_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_CHARLES -> F4_top
        F4_top -> NEWTON_CHARLOTTE
    }

I’m unclear what the practical difference is.

Nope, you are defining subgraphs, not clusters.
Clusters are best explained in section 3.2 of https://www.graphviz.org/pdf/dotguide.pdf.
In short, subgraphs (in braces) define logical collections of nodes. Clusters define physical collections of nodes.
[Except for the dotguide document, the Graphviz documentation does a poor job of explaining this]

1 Like

I see. Unfortunately, using clusters in my original code just leads to more of a mess. The best output I can get is for the following two-generation tree:

digraph {
    splines = ortho;
    node [shape=box]
    edge [dir=none]

    subgraph clusterF3 {
        peripheries=0;
        SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];
        JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
        F3_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_ADAM -> F3_top
        F3_top -> JONES_MARY
    }
    {
        rank=same;
        F3_0 [shape=circle, label="", height=0.01, width=0.01];
        F3_1 [shape=circle, label="", height=0.01, width=0.01];
        F3_2 [shape=circle, label="", height=0.01, width=0.01];
        F3_0 -> F3_1 -> F3_2;
    }
    F3_top -> F3_1;
    F3_0 -> SMITH_JOHN;
    F3_2 -> SMITH_JANE;

    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];
}

[dot]

digraph {
    splines = ortho;
    node [shape=box]
    edge [dir=none]

    subgraph clusterF3 {
        peripheries=0;
        SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];
        JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
        F3_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_ADAM -> F3_top
        F3_top -> JONES_MARY
    }
    {
        rank=same;
        F3_0 [shape=circle, label="", height=0.01, width=0.01];
        F3_1 [shape=circle, label="", height=0.01, width=0.01];
        F3_2 [shape=circle, label="", height=0.01, width=0.01];
        F3_0 -> F3_1 -> F3_2;
    }
    F3_top -> F3_1;
    F3_0 -> SMITH_JOHN;
    F3_2 -> SMITH_JANE;

    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];
}

[/dot]

Here, Adam Smith and Mary Jones are laid out from top to bottom instead of from left to right. Adding rank=same; and/or rankdir="LR"; to the cluster doesn’t change anything.

That we can fix. Add {rank=same inside each cluster, like so:

digraph {
    splines = ortho;
    node [shape=box]
    edge [dir=none]

    subgraph clusterF3 {
    peripheries=0;
     { rank=same  // placed inside the cluster
        SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];
        JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
        F3_top [shape=circle, label="", height=0.01, width=0.01];
        SMITH_ADAM -> F3_top
        F3_top -> JONES_MARY
      }
    }
    {
        rank=same;
        F3_0 [shape=circle, label="", height=0.01, width=0.01];
        F3_1 [shape=circle, label="", height=0.01, width=0.01];
        F3_2 [shape=circle, label="", height=0.01, width=0.01];
        F3_0 -> F3_1 -> F3_2;
    }
    F3_top -> F3_1;
    F3_0 -> SMITH_JOHN;
    F3_2 -> SMITH_JANE;

    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];
}

Giving:

1 Like

OK, I’ve now got the nodes in the great-grandparents family tree positioned correctly with:

digraph {
    splines = ortho;
    node [shape=box]
    edge [dir=none]

    SMITH_BRIDGET [label="Bridget Smith", style=filled, fillcolor=bisque];
    SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];

    SMITH_BERTRAND [label="Bertrand Smith", style=filled, fillcolor=azure2];
    JOHNSON_BEATRICE [label="Beatrice Johnson", style=filled, fillcolor=bisque];

    SMITH_CHARLES [label="Charles Smith", style=filled, fillcolor=azure2];
    NEWTON_CHARLOTTE [label="Charlotte Newton", style=filled, fillcolor=bisque];

    JOHNSON_BAINES [label="Baines Johnson", style=filled, fillcolor=azure2];
    MAXWELL_MARGARET [label="Margaret Maxwell", style=filled, fillcolor=bisque];

    JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
    JONES_HENRY_JR [label="Henry Jones Junior", style=filled, fillcolor=azure2];
    JONES_DIANA [label="Diana Jones", style=filled, fillcolor=bisque];

    JONES_HENRY [label="Henry Jones", style=filled, fillcolor=azure2];
    ADAMS_ABIGAIL [label="Abigail Adams", style=filled, fillcolor=bisque];

    JONES_JEREMIAH [label="Jeremiah Jones", style=filled, fillcolor=azure2];
    PLANK_PATRICIA [label="Patricia Plank", style=filled, fillcolor=bisque];

    ADAMS_DOUGLAS [label="Douglas Adams", style=filled, fillcolor=azure2];
    DENT_URSULA [label="Ursula Dent", style=filled, fillcolor=bisque];

    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];

    subgraph clusterF1 {
        peripheries=0;
        {
            rank=same;
            F1_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_BERTRAND -> F1_top
            F1_top -> JOHNSON_BEATRICE
        }
    }
    {
        rank=same;
        F1_0 [shape=circle, label="", height=0.01, width=0.01];
        F1_1 [shape=circle, label="", height=0.01, width=0.01];
        F1_2 [shape=circle, label="", height=0.01, width=0.01];
        F1_0 -> F1_1 -> F1_2;
    }
    F1_top -> F1_1;
    F1_0 -> SMITH_BRIDGET;
    F1_2 -> SMITH_ADAM;

    subgraph clusterF2 {
        peripheries=0;
        {
            rank=same;
            F2_top [shape=circle, label="", height=0.01, width=0.01];
            JONES_HENRY -> F2_top
            F2_top -> ADAMS_ABIGAIL
        }
    }
    {
        rank=same;
        F2_0 [shape=circle, label="", height=0.01, width=0.01];
        F2_1 [shape=circle, label="", height=0.01, width=0.01];
        F2_2 [shape=circle, label="", height=0.01, width=0.01];
        F2_0 -> F2_1 -> F2_2;
    }
    F2_top -> F2_1;
    F2_0 -> JONES_MARY;
    F2_1 -> JONES_HENRY_JR;
    F2_2 -> JONES_DIANA;

    subgraph clusterF3 {
        peripheries=0;
        {
            rank=same;
            F3_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_ADAM -> F3_top
            F3_top -> JONES_MARY
        }
    }
    {
        rank=same;
        F3_0 [shape=circle, label="", height=0.01, width=0.01];
        F3_1 [shape=circle, label="", height=0.01, width=0.01];
        F3_2 [shape=circle, label="", height=0.01, width=0.01];
        F3_0 -> F3_1 -> F3_2;
    }
    F3_top -> F3_1;
    F3_0 -> SMITH_JOHN;
    F3_2 -> SMITH_JANE;

    subgraph clusterF4 {
        peripheries=0;
        {
            rank=same;
            F4_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_CHARLES -> F4_top
            F4_top -> NEWTON_CHARLOTTE
        }
    }
    {
        rank=same;
        F4_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F4_top -> F4_0;
    F4_0 -> SMITH_BERTRAND;

    subgraph clusterF5 {
        peripheries=0;
        {
            rank=same;
            F5_top [shape=circle, label="", height=0.01, width=0.01];
            JOHNSON_BAINES -> F5_top
            F5_top -> MAXWELL_MARGARET
        }
    }
    {
        rank=same;
        F5_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F5_top -> F5_0;
    F5_0 -> JOHNSON_BEATRICE;

    subgraph clusterF6 {
        peripheries=0;
        {
            rank=same;
            F6_top [shape=circle, label="", height=0.01, width=0.01];
            JONES_JEREMIAH -> F6_top
            F6_top -> PLANK_PATRICIA
        }
    }
    {
        rank=same;
        F6_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F6_top -> F6_0;
    F6_0 -> JONES_HENRY;

    subgraph clusterF7 {
        peripheries=0;
        {
            rank=same;
            F7_top [shape=circle, label="", height=0.01, width=0.01];
            ADAMS_DOUGLAS -> F7_top
            F7_top -> DENT_URSULA
        }
    }
    {
        rank=same;
        F7_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F7_top -> F7_0;
    F7_0 -> ADAMS_ABIGAIL;
}

[dot]

digraph {
    splines = ortho;
    node [shape=box]
    edge [dir=none]

    SMITH_BRIDGET [label="Bridget Smith", style=filled, fillcolor=bisque];
    SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];

    SMITH_BERTRAND [label="Bertrand Smith", style=filled, fillcolor=azure2];
    JOHNSON_BEATRICE [label="Beatrice Johnson", style=filled, fillcolor=bisque];

    SMITH_CHARLES [label="Charles Smith", style=filled, fillcolor=azure2];
    NEWTON_CHARLOTTE [label="Charlotte Newton", style=filled, fillcolor=bisque];

    JOHNSON_BAINES [label="Baines Johnson", style=filled, fillcolor=azure2];
    MAXWELL_MARGARET [label="Margaret Maxwell", style=filled, fillcolor=bisque];

    JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
    JONES_HENRY_JR [label="Henry Jones Junior", style=filled, fillcolor=azure2];
    JONES_DIANA [label="Diana Jones", style=filled, fillcolor=bisque];

    JONES_HENRY [label="Henry Jones", style=filled, fillcolor=azure2];
    ADAMS_ABIGAIL [label="Abigail Adams", style=filled, fillcolor=bisque];

    JONES_JEREMIAH [label="Jeremiah Jones", style=filled, fillcolor=azure2];
    PLANK_PATRICIA [label="Patricia Plank", style=filled, fillcolor=bisque];

    ADAMS_DOUGLAS [label="Douglas Adams", style=filled, fillcolor=azure2];
    DENT_URSULA [label="Ursula Dent", style=filled, fillcolor=bisque];

    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];

    subgraph clusterF1 {
        peripheries=0;
        {
            rank=same;
            F1_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_BERTRAND -> F1_top
            F1_top -> JOHNSON_BEATRICE
        }
    }
    {
        rank=same;
        F1_0 [shape=circle, label="", height=0.01, width=0.01];
        F1_1 [shape=circle, label="", height=0.01, width=0.01];
        F1_2 [shape=circle, label="", height=0.01, width=0.01];
        F1_0 -> F1_1 -> F1_2;
    }
    F1_top -> F1_1;
    F1_0 -> SMITH_BRIDGET;
    F1_2 -> SMITH_ADAM;

    subgraph clusterF2 {
        peripheries=0;
        {
            rank=same;
            F2_top [shape=circle, label="", height=0.01, width=0.01];
            JONES_HENRY -> F2_top
            F2_top -> ADAMS_ABIGAIL
        }
    }
    {
        rank=same;
        F2_0 [shape=circle, label="", height=0.01, width=0.01];
        F2_1 [shape=circle, label="", height=0.01, width=0.01];
        F2_2 [shape=circle, label="", height=0.01, width=0.01];
        F2_0 -> F2_1 -> F2_2;
    }
    F2_top -> F2_1;
    F2_0 -> JONES_MARY;
    F2_1 -> JONES_HENRY_JR;
    F2_2 -> JONES_DIANA;

    subgraph clusterF3 {
        peripheries=0;
        {
            rank=same;
            F3_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_ADAM -> F3_top
            F3_top -> JONES_MARY
        }
    }
    {
        rank=same;
        F3_0 [shape=circle, label="", height=0.01, width=0.01];
        F3_1 [shape=circle, label="", height=0.01, width=0.01];
        F3_2 [shape=circle, label="", height=0.01, width=0.01];
        F3_0 -> F3_1 -> F3_2;
    }
    F3_top -> F3_1;
    F3_0 -> SMITH_JOHN;
    F3_2 -> SMITH_JANE;

    subgraph clusterF4 {
        peripheries=0;
        {
            rank=same;
            F4_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_CHARLES -> F4_top
            F4_top -> NEWTON_CHARLOTTE
        }
    }
    {
        rank=same;
        F4_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F4_top -> F4_0;
    F4_0 -> SMITH_BERTRAND;

    subgraph clusterF5 {
        peripheries=0;
        {
            rank=same;
            F5_top [shape=circle, label="", height=0.01, width=0.01];
            JOHNSON_BAINES -> F5_top
            F5_top -> MAXWELL_MARGARET
        }
    }
    {
        rank=same;
        F5_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F5_top -> F5_0;
    F5_0 -> JOHNSON_BEATRICE;

    subgraph clusterF6 {
        peripheries=0;
        {
            rank=same;
            F6_top [shape=circle, label="", height=0.01, width=0.01];
            JONES_JEREMIAH -> F6_top
            F6_top -> PLANK_PATRICIA
        }
    }
    {
        rank=same;
        F6_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F6_top -> F6_0;
    F6_0 -> JONES_HENRY;

    subgraph clusterF7 {
        peripheries=0;
        {
            rank=same;
            F7_top [shape=circle, label="", height=0.01, width=0.01];
            ADAMS_DOUGLAS -> F7_top
            F7_top -> DENT_URSULA
        }
    }
    {
        rank=same;
        F7_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F7_top -> F7_0;
    F7_0 -> ADAMS_ABIGAIL;
}

[/dot]

There’s some weirdness with the edges, and the order in which the person nodes are declared still sometimes has an impact on the results (and I’ll still probably end up making another post about that later), but this seems acceptable for now.

To summarize: The subgraph for each marriage relationship (containing the spouses and the “dot” in between them) should be made into a cluster by giving it an explicit name that starts with “cluster”. Within this cluster, set peripheries=0; and create a non-cluster sub-subgraph containing the nodes themselves with rank=same;.

the ortho algorithm has a bunch of issues (see Work items · graphviz / graphviz · GitLab)

Here is a modestly improved version that uses Graphviz post-processor to customize edges · GitHub (see also A program to "fix" simple edges)

command line:
f=forum3328_3.gv; T=png;F=${f%.*};dot $f |gvpr -cf alterSimpleEdge.gvpr|neato -n2 -T$T -o$F.$T

digraph {
    //splines = ortho;
    node [shape=box]
    edge [dir=none]
edge [edgeType=ortho2]

    SMITH_BRIDGET [label="Bridget Smith", style=filled, fillcolor=bisque];
    SMITH_ADAM [label="Adam Smith", style=filled, fillcolor=azure2];

    SMITH_BERTRAND [label="Bertrand Smith", style=filled, fillcolor=azure2];
    JOHNSON_BEATRICE [label="Beatrice Johnson", style=filled, fillcolor=bisque];

    SMITH_CHARLES [label="Charles Smith", style=filled, fillcolor=azure2];
    NEWTON_CHARLOTTE [label="Charlotte Newton", style=filled, fillcolor=bisque];

    JOHNSON_BAINES [label="Baines Johnson", style=filled, fillcolor=azure2];
    MAXWELL_MARGARET [label="Margaret Maxwell", style=filled, fillcolor=bisque];

    JONES_MARY [label="Mary Jones", style=filled, fillcolor=bisque];
    JONES_HENRY_JR [label="Henry Jones Junior", style=filled, fillcolor=azure2];
    JONES_DIANA [label="Diana Jones", style=filled, fillcolor=bisque];

    JONES_HENRY [label="Henry Jones", style=filled, fillcolor=azure2];
    ADAMS_ABIGAIL [label="Abigail Adams", style=filled, fillcolor=bisque];

    JONES_JEREMIAH [label="Jeremiah Jones", style=filled, fillcolor=azure2];
    PLANK_PATRICIA [label="Patricia Plank", style=filled, fillcolor=bisque];

    ADAMS_DOUGLAS [label="Douglas Adams", style=filled, fillcolor=azure2];
    DENT_URSULA [label="Ursula Dent", style=filled, fillcolor=bisque];

    SMITH_JOHN [label="John Smith", style=filled, fillcolor=azure2];
    SMITH_JANE [label="Jane Smith", style=filled, fillcolor=bisque];

    subgraph clusterF1 {
        peripheries=0;
        {
            rank=same;
            F1_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_BERTRAND -> F1_top
            F1_top -> JOHNSON_BEATRICE
        }
    }
    {
        rank=same;
        F1_0 [shape=circle, label="", height=0.01, width=0.01];
        F1_1 [shape=circle, label="", height=0.01, width=0.01];
        F1_2 [shape=circle, label="", height=0.01, width=0.01];
        F1_0 -> F1_1 -> F1_2;
    }
    F1_top -> F1_1   // gives diagonal [edgeType=straight]  // added
    F1_0 -> SMITH_BRIDGET [edgeType=straight]  // added
    F1_2 -> SMITH_ADAM;

    subgraph clusterF2 {
        peripheries=0;
        {
            rank=same;
            F2_top [shape=circle, label="", height=0.01, width=0.01];
            JONES_HENRY -> F2_top
            F2_top -> ADAMS_ABIGAIL
        }
    }
    {
        rank=same;
        F2_0 [shape=circle, label="", height=0.01, width=0.01];
        F2_1 [shape=circle, label="", height=0.01, width=0.01];
        F2_2 [shape=circle, label="", height=0.01, width=0.01];
        F2_0 -> F2_1 -> F2_2;
    }
    F2_top -> F2_1;
    F2_0 -> JONES_MARY [edgeDirection=ccw]
    F2_1 -> JONES_HENRY_JR;
    F2_2 -> JONES_DIANA;

    subgraph clusterF3 {
        peripheries=0;
        {
            rank=same;
            F3_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_ADAM -> F3_top
            F3_top -> JONES_MARY
        }
    }
    {
        rank=same;
        F3_0 [shape=circle, label="", height=0.01, width=0.01];
        F3_1 [shape=circle, label="", height=0.01, width=0.01];
        F3_2 [shape=circle, label="", height=0.01, width=0.01];
        F3_0 -> F3_1 -> F3_2;
    }
    F3_top -> F3_1;
    F3_0 -> SMITH_JOHN;
    F3_2 -> SMITH_JANE;

    subgraph clusterF4 {
        peripheries=0;
        {
            rank=same;
            F4_top [shape=circle, label="", height=0.01, width=0.01];
            SMITH_CHARLES -> F4_top
            F4_top -> NEWTON_CHARLOTTE
        }
    }
    {
        rank=same;
        F4_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F4_top -> F4_0 [edgeDirection=ccw]
    F4_0 -> SMITH_BERTRAND 

    subgraph clusterF5 {
        peripheries=0;
        {
            rank=same;
            F5_top [shape=circle, label="", height=0.01, width=0.01];
            JOHNSON_BAINES -> F5_top
            F5_top -> MAXWELL_MARGARET
        }
    }
    {
        rank=same;
        F5_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F5_top -> F5_0;
    F5_0 -> JOHNSON_BEATRICE;

    subgraph clusterF6 {
        peripheries=0;
        {
            rank=same;
            F6_top [shape=circle, label="", height=0.01, width=0.01];
            JONES_JEREMIAH -> F6_top
            F6_top -> PLANK_PATRICIA
        }
    }
    {
        rank=same;
        F6_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F6_top -> F6_0;
    F6_0 -> JONES_HENRY;

    subgraph clusterF7 {
        peripheries=0;
        {
            rank=same;
            F7_top [shape=circle, label="", height=0.01, width=0.01];
            ADAMS_DOUGLAS -> F7_top
            F7_top -> DENT_URSULA
        }
    }
    {
        rank=same;
        F7_0 [shape=circle, label="", height=0.01, width=0.01];
    }
    F7_top -> F7_0;
    F7_0 -> ADAMS_ABIGAIL [edgeDirection=ccw]
}

Giving:

I realize that this is really a bus (as in busbar) problem (see: Drawing busses for network and other diagrams (#1987) · Issues · graphviz / graphviz · GitLab).

I may have a better solution in the dusty corners of my computer. looking …