Is there a way to construct a tree whose children are located at
specified positions, so that TikZ computes the locations of the
other nodes in the tree based on the level distance and sibling
distance?
I ask because, ultimately, I have a matrix of nodes and would like
to grow a tree into the second column's vector from the righthand
side. A minimal working example of what I have so far is:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,matrix}
\begin{document}
\tikzset{
img/.initial={},
img/.value required,
%
image placeholder/.style={%
execute at end node=\phantom{\pgfuseimage{\pgfkeysvalueof{/tikz/img}}}}
}
\pgfdeclareimage[height=7em]{ballot}{fptp-ballot}
\begin{tikzpicture}[every node/.style={draw=black},
every matrix/.style={ampersand replacement=\&}]
\matrix (ballot counts)
[matrix of nodes, nodes in empty cells, cells={right},
column 1/.append style={%
nodes={scale=0.5}, image placeholder, img=ballot}]
{
\& Alice: $0$ \\
\& Bob: $0$ \\
\& Charlie: $0$ \\
\& Dave: $0$ \\
};
\matrix (ballot box)
[node distance=2 and 2, right=of ballot counts,
matrix of nodes, nodes in empty cells,
cells={image placeholder, img=ballot}]
{
\& \\
\& \\
};
\matrix (max tree)
[matrix anchor=west]
at (ballot counts.east)
{
\node {root} [grow=left, level/.style={sibling distance=7em/#1}]
child {node {left}
child {node {}}
child {node {}}}
child {node {right}
child {node {}}
child {node {}}}; \\
};
\end{tikzpicture}
\end{document}

I would like to modify this diagram so that the leaves of max tree attach to the four entries in second column of ballot counts (i.e., Alice: 0, ...).
In an earlier version of this question, @TomBombadil suggested that I could use at to explicitly position the leaves of the tree. The problem with that is that then the interior nodes will also have to be positioned explicitly. I was hoping for some way to leverage level distance and sibling distance.
Edit: Based on @percusse's comment that "growing the tree and putting nodes left of each sibling" might be an answer, I came up with the following MWE that does, more or less, what I want. (@percusse: Is this what you were getting at, or were you thinking something different?)
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,positioning,matrix,fit}
\begin{document}
\tikzset{
img/.initial={},
img/.value required,
%
image placeholder/.style={%
execute at end node=\phantom{\pgfuseimage{\pgfkeysvalueof{/tikz/img}}}}
}
\pgfdeclareimage[height=7em]{ballot}{fptp-ballot}
\tikzstyle{ballot count} = [matrix of nodes, nodes in empty cells,
right, inner sep=0em,
cells={right, inner sep=0.3333em},
column 1/.append style={%
image placeholder, img=ballot, nodes={scale=0.5}}]
\begin{tikzpicture}[every node/.style={draw},
every matrix/.style={ampersand replacement=\&}]
% Construct a fake ballot count ``leaf'' to measure its height.
\matrix (tmp) [ballot count, overlay,
draw=none, nodes={draw=none}]
{ \\ };
% Measure the height of the fake ``leaf''.
\path let \p{childheight} = ($(tmp.north)-(tmp.south)$) in
% Use the height to set sibling distance so that
% there is no gap between the leaves of the tree.
[level/.append style={sibling distance=2*\y{childheight}/#1,
level distance=2cm*#1}]
node {root} [grow=left]
child {node {left}
child [child anchor=east] foreach \name in {Alice, Bob}
{node (\name's count) [matrix, ballot count]
{ \& \name: $0$ \\ }}}
child {node {right}
child [child anchor=east] foreach \name in {Charlie, Dave}
{node (\name's count) [matrix, ballot count]
{ \& \name: $0$ \\ }}};
% Build the bounding box that contains all leaves.
\node (ballot counts)
[inner sep=0em,
fit=(Alice's count) (Bob's count)
(Charlie's count) (Dave's count)] {};
% Position a matrix to the right of the leaves.
\matrix (ballot box)
[node distance=2 and 2, right=of ballot counts,
matrix of nodes, nodes in empty cells,
cells={image placeholder, img=ballot}]
{
\& \\
\& \\
};
\end{tikzpicture}
\end{document}

This approach has several drawbacks:
I have to create a fake leaf, named
tmp, to measure the height of an arbitrary leaf. It would be better if I could somehow measure the height of a leaf and then retroactively pass this height to thesibling distancefor the tree.Since the leaves are no longer within a matrix, I have to explicitly construct a bounding box in order to position
ballot boxwhere I want it to be. Also, the code for the leaves is now spread among the two subtrees; this complicates the description of the tree edges and non-leaf nodes, and requires that some of the code is duplicated across subtrees.
I guess, in general, the code is not as clean as I would have liked; I'm still hoping that there is a cleaner solution. But perhaps I just need to learn to be less greedy. :)


barycentric cs. when you are stuck with the positions of the children nodes, i don't know how to do using the tree library unfortunatelly. it would be cool if we could build the tree from the roots, instead of the head... does someone know how to do so? – sylcha Jun 09 '12 at 01:00(ballot counts-1-2.east)etc. while keeping the level 1 nodes in the middle of the two names vertically. Thanks! – Henry DeYoung Jun 20 '12 at 22:40\node [image, img=ballotbob] at (ballot box-1-1) {};. The images have to be in separate nodes because they will be animated moving into theimage placeholderposition in the appropriate leaf of the tree. So, really, I'm using\node [image, img=ballotbob] at ($(ballot box-1-1)!\loc!(Bob's count-1-1)$) {};, where\locincreases from0to1during the animation. I wanted to leave the window-likeballot boxin my question to hint at why I used a 4-by-2 matrix forballot countsoriginally. – Henry DeYoung Jun 21 '12 at 21:420.5*(7+0.3333) emwhich are known and set by you.0.5is the node scaling. Do you want to keep it as it is? – percusse Jun 21 '12 at 22:45sibling distance. Also, there is still drawback #2 above, but, as I said, perhaps I just need to learn to be less greedy. – Henry DeYoung Jun 22 '12 at 01:13