2

by default tikz grows trees in a centered manner, such that children grow as:

     o
   /   \
  o     o
 / \   / \
o   o o   o

How can I grow the trees such that they grow down, then right? Such that:

o
|  \
o     o
| \   | \
o  o  o  o

I started with the following code to build the first, centered tikz tree:

\documentclass[border=5pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}[
    every node/.style={circle,draw},
    level 1/.style={sibling distance=4cm},
    level 2/.style={sibling distance=2cm},
    level 3/.style={sibling distance=1cm},
  ]
  \node {1}
    child {node {2}
      child {node {4}}
      child {node {5}}
    }
    child {node {3}
      child {node {6}}
      child {node {7}}
    };
\end{tikzpicture}
\end{document}

and I have gotten somewhere by adding the option grow=down to children (but the other child nodes are still misaligned..). However, I cannot figure out how to make these trees grow automatically the correct way. Is there a straightforward solution here?

1
  • Welcome! Are you open to a solution using a different package? This is easy with forest.
    – cfr
    Commented Jun 20 at 16:16

1 Answer 1

2

In forest, you can use different calign settings to change the way children are aligned with respect to their parents or, more accurately, the way parents are aligned with respect to their children.

For example,

    calign primary child=1,

This makes the first child the 'primary' child.

    calign=child edge,

This aligns the parent node with its first child. More precisely, it aligns the parent's parent anchor with the child's child anchor. The result is that the edge between them aligns with the direction of the tree's growth.

parent aligned to first child

I also added fit=band because forest has a problem drawing some trees when the nodes have the shape circle. (I think the problem occurs either when the tree is 'packed' or when the x-y coordinates are calculated right after packing, but I'm not sure.)

\begin{forest}
  for tree={%
    circle,
    fit=band,
    draw,
    calign primary child=1,
    calign=child edge,
  },
  [1
    [2
      [4][5]
    ]
    [3
      [6][7]
    ]
  ]
\end{forest}

If you'd rather not deal with forest, you can create 'phantom' nodes to force alignment in a regular tikz tree, though you will probably want to adjust the sibling distances.

For example (without adjustments),

\begin{tikzpicture}[
  every node/.style={circle,draw},
  level 1/.style={sibling distance=4cm},
  level 2/.style={sibling distance=2cm},
  level 3/.style={sibling distance=1cm},
  phantom/.style={draw=none,coordinate},
  ]
  \node {1}
  child {node [phantom] {} edge from parent[phantom]}
  child {node {2}
    child {node [phantom] {} edge from parent[phantom]}
    child {node {4}}
    child {node {5}}
  }
  child {node {3}
    child {node [phantom] {} edge from parent[phantom]}
    child {node {6}}
    child {node {7}}
  };
\end{tikzpicture}

with 'phantom' children

If we do not mind spreading the children further, we could also use forest in a different way which ensures the edges run straight from the root to the grandchildren, without changing direction at the intermediate level.

For example,

\begin{forest}
  for tree={%
    circle,
    fit=band,
    draw,
    calign primary angle=0,
    calign secondary angle=55,
    calign=fixed edge angles,
  },
  [1
    [2
      [4][5]
    ]
    [3
      [6][7]
    ]
  ]
\end{forest}

straightened edges

    calign primary angle=0,

This is the angle between the direction of growth of the tree (-90 by default) and the primary child's edge (if calign=fixed edge angles is used). So setting it to 0 ensures the parent is aligned with the primary child.

    calign secondary angle=55,

Similar, but for the secondary child. By default, this is the last child and the primary child is the first.

    calign=fixed edge angles,

Tells forest what to do with the angles we just set. Specifically, tells it to arrange the parent relative to its children so that the edges drawn between them are always at the specified angles, relative to the tree's direction of growth1.

Complete code:

\documentclass[border=5pt,tikz]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
  for tree={%
    circle,
    fit=band,
    draw,
    calign primary child=1,
    calign=child edge,
  },
  [1
    [2
      [4][5]
    ]
    [3
      [6][7]
    ]
  ]
\end{forest}
\begin{forest}
  for tree={%
    circle,
    fit=band,
    draw,
    calign primary angle=0,
    calign secondary angle=55,
    calign=fixed edge angles,
  },
  [1
    [2
      [4][5]
    ]
    [3
      [6][7]
    ]
  ]
\end{forest}
\begin{tikzpicture}[
  every node/.style={circle,draw},
  level 1/.style={sibling distance=4cm},
  level 2/.style={sibling distance=2cm},
  level 3/.style={sibling distance=1cm},
  phantom/.style={draw=none,coordinate},
  ]
  \node {1}
  child {node [phantom] {} edge from parent[phantom]}
  child {node {2}
    child {node [phantom] {} edge from parent[phantom]}
    child {node {4}}
    child {node {5}}
  }
  child {node {3}
    child {node [phantom] {} edge from parent[phantom]}
    child {node {6}}
    child {node {7}}
  };
\end{tikzpicture}
\end{document}

Or you could use the graphing facilities of TikZ, with or without Lua.

1At least, that is what should happen. It is also what does happen in 'standard' cases. But there are some bugs which mean it does not always work as it should if the tree grows in a different direction.

1
  • Thank you for the in-depth answer this is exactly what I needed!
    – Reginald
    Commented Jun 20 at 19:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .