1

I am trying to draw a representation of a statistical multi-level model: examples of what I am trying to do can be seen in figures 3a or 3b, at http://www.esourceresearch.org/tabid/332/Default.aspx.

enter image description here

I have made an attempt, but cannot get the spacing correct. In the figure below, the children of c1 and cn overlap (so that only the child of cn can be seen). I also do not know how to appropriately add the dots between each of the levels: between one and two and two and n, and between t1 and tn, and so on. I tried just adding an extra child node, but I from the looks of it, it is not the way to go. Thanks.

enter image description here

My code

\documentclass{article}    
\usepackage[landscape, left=10pt]{geometry} 
\usepackage{tikz}    
\begin{document}

% styles
\tikzstyle{every node} = [rectangle, draw,  text centered, rounded corners, fill=blue!20, minimum height=1cm, minimum width=1cm]

\begin{tikzpicture}[sibling distance=1.25cm]

\node { one } 
  child { node {c1}
    child { node {t1}}
    child { node [draw=none] {\ldots}}
    child { node {tn}}
  }
  child { node [draw=none] {\ldots}
  }
  child { node {cn}
    child { node {t1}}
    child { node [draw=none] {\ldots}}
    child { node {tn}}
  }
  ;

\hspace*{7cm} \node { two }
  child { node {c1}
    child { node {t1}}
    child { node [draw=none] {\ldots}}
    child { node {tn}}
  }
  child { node [draw=none] {\ldots}
  }
  child { node {cn}
    child { node {t1}}
    child { node [draw=none] {\ldots}}
    child { node {tn}}
   };

\hspace*{7cm} \node { n }
  child { node {c1}
    child { node {t1}}
    child { node [draw=none] {\ldots}}
    child { node {tn}}
  }
  child { node [draw=none] {\ldots}
  }
  child { node {cn}
    child { node {t1}}
    child { node [draw=none] {\ldots}}
    child { node {tn}}
   };

\end{tikzpicture}

\end{document}
3

May I recommend the specialist tree-drawing package, Forest?

\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
\usetikzlibrary{shadows}
\begin{document}

\begin{forest}
  for tree={
    math content,
  },
  delay={
    where content={}{
      if level=0{}{
        content=\ldots,
        math content,
        no edge,
        fit=band,
      },
    }{
      rounded corners,
      outer color=blue!20,
      inner color=blue!15,
      minimum height=1cm,
      minimum width=1cm,
      draw,
      drop shadow,
    },
  }
  [, phantom
    [one, plain content
      [c_1
        [t_1]
        []
        [t_n]
      ]
      []
      [c_n
        [t_1]
        []
        [t_n]
      ]
    ]
    [two, plain content
      [c_1
        [t_1]
        []
        [t_n]
      ]
      []
      [c_n
        [t_1]
        []
        [t_n]
      ]
    ]
    []
    [n
      [c_1
        [t_1]
        []
        [t_n]
      ]
      []
      [c_n
        [t_1]
        []
        [t_n]
      ]
    ]
  ]
\end{forest}

\end{document}

Forest tree

EDIT

Here's a fancier version which defines label levels as a style for trees which should have level labels. Labels should be added within the tree using level label=<label text> and will be concatenated to form a label for that level, preceded by the prefix Label <level number>. All of this can be adjusted, of course.

I've also added a fancier background, but that's obviously strictly optional.

\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
\usetikzlibrary{shadows,fit,backgrounds}
\forestset{
  declare toks={level label}{},
  declare toks register={level labels},
  level labels={},
  declare count register={leveller},
  leveller'=0,
  level split/.style={
    temptoksa={#1},
    split register={temptoksa}{:}{tempcounta,level label split},
  },
  level label split/.style={
    temptoksb={#1},
    temptoksc={},
    split register={temptoksb}{,}{temptoksc, level label splitter},
    tikz+/.wrap 2 pgfmath args={
      \node (label leveller ##1) [anchor=east, align=right, font=\sffamily] at (level ##1.west -| westpoint) {##2};
    }{tempcounta}{temptoksc},
    before computing xy/.wrap pgfmath arg={
      tikz+={
        \node [anchor=north east, align=right, font=\sffamily\itshape] at (label leveller ##1.north -| west of westpoint) {Level ##1};
      },
    }{tempcounta},
  },
  level label splitter/.style={
    temptoksc+={\\#1},
  },
  label levels/.style={
    tikz+={
      \coordinate (westpoint) at ([xshift=-15pt]current bounding box.west);
    },
    before packing={
        tikz+={
        \coordinate (west of westpoint) at ([xshift=-15pt]current bounding box.west);
      },
    },
    before drawing tree={
      tikz+={
        \scoped[on background layer]{\node [left color=blue!50!cyan!25!white, right color=blue!50!cyan!25!white, middle color=blue!50!cyan, inner sep=10pt, rounded corners, draw=blue!50!cyan, draw opacity=.5, fill opacity=.15, fit=(current bounding box)] {};}
      },
    },
    delay={
      for tree breadth-first={
        if level label={}{}{
          if={(level())>(leveller)}{
            leveller/.option=level,
            alias/.wrap pgfmath arg={level ##1}{level()},
            if level labels={}{}{
              level labels+={;},
            },
            level labels+/.option=level,
            level labels+={:},
          }{},
          level labels+/.option=level label,
          level labels+={,},
        },
      },
    },
    before typesetting nodes={
      if level labels={}{}{
        split register={level labels}{;}{level split},
      },
    },
  }
}
\begin{document}

\begin{forest}
  for tree={
    math content,
  },
  delay={
    where content={}{
      if level=0{}{
        content=\ldots,
        math content,
        no edge,
        fit=band,
      },
    }{
      rounded corners,
      outer color=blue!20,
      inner color=blue!15,
      minimum height=1cm,
      minimum width=1cm,
      draw,
      drop shadow,
    },
  },
  label levels,
  [, phantom
    [one, plain content, level label=platitudes
      [c_1
        [t_1]
        []
        [t_n]
      ]
      []
      [c_n
        [t_1]
        []
        [t_n]
      ]
    ]
    [two, plain content
      [c_1
        [t_1, level label=latitudes]
        []
        [t_n]
      ]
      []
      [c_n
        [t_1]
        []
        [t_n, level label=longitudes]
      ]
    ]
    []
    [n
      [c_1, level label=magnitudes
        [t_1]
        []
        [t_n]
      ]
      []
      [c_n
        [t_1]
        []
        [t_n]
      ]
    ]
  ]
\end{forest}

\end{document}

fancier with labelled levels

7
  • If you want the level labels at the left, let me know. justtrees can do this straightforwardly and I need stuff to test it on. Or I can just show you how to do it a little less straightforwardly without justtrees ;).
    – cfr
    Oct 11 '16 at 16:02
  • that looks great, thank you. I had actually noticed a few of your previous posts usingforest but hadn't managed to produce anything reasonable. If there is a way to adapt this to add labels on the left that would be great, but as is im very happy.
    – user20650
    Oct 11 '16 at 16:41
  • @user20650 Please see edit above. Forest takes some getting used to, but it is really nice and well worth the effort.
    – cfr
    Oct 11 '16 at 23:18
  • That looks really great. Thank you so much. As I mentioned above, I had seen your previous forest answers, but I had found the syntax a little to grasp. But im convinced, to make an effort. Is the ctan.org/pkg/forest guide best place to start?
    – user20650
    Oct 11 '16 at 23:39
  • 1
    @user20650 Yes. For a simple introduction to the syntax, you might try this answer of mine: tex.stackexchange.com/questions/5447/…. The question is not about Forest, so it doesn't have the forest tag, but I try to give a very basic intro to Forest in the answer.
    – cfr
    Oct 11 '16 at 23:56

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.