1

before

i need to arrange the above Forest tree in a configuration similar to this sketch diagram.

how am i able to arrange the nodes such that the '0' edge points directly south and the '1' edge is at a right angle to it and points directly east?

i need this is to be the same for all of the nodes which have all '0' prefixes (i.e. 0,00,000,0000)

any help would be great, i'm completely stumped.

additionally i need to add in the dividing horizontal lines and the annotations on the right hand side, i guess with tikz.

after

% not sure about these colours!
\definecolor{c1}{HTML}{FF7F00}
\definecolor{c2}{HTML}{048BA8}
\definecolor{c3}{HTML}{16DB93}
\definecolor{c4}{HTML}{EFEA5A}
\definecolor{c5}{HTML}{F29E4C}
\definecolor{c6}{HTML}{256EFF}
\definecolor{c7}{HTML}{46237A}


\scalebox{1.35}{
\begin{forest}
rt/.style={draw=green,line width=1pt},
peer/.style={draw=blue!60,edge={blue!60,line width=0.7pt}},
peerleaf/.style={edge={blue!60,line width=0.7pt}},
self/.style={draw=blue,fill=blue,edge={blue,line width=1pt}},
selfpeer/.style={draw=blue,line width=1pt,edge={blue,line width=1pt}},
unused/.style={draw=blue!20,edge={blue!20,line width=0.7pt}},
[{},grow=east, rt,for tree={circle,draw, l sep=20pt}
  [{},grow=east,selfpeer,edge label={node[midway,left] {0}}
    [{},grow=east,selfpeer,edge label={node[midway,left] {0}}
      [{},grow=east,selfpeer,edge label={node[midway,left] {0}}
        [{},grow=east,self,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c3,fill=c3,peerleaf,edge label={node[midway,right] {1}}]
      ]
      [{},grow=east,peer,edge label={node[midway,right] {1}}
        [{},grow=east,draw=c4,fill=c5,peerleaf,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c4,fill=c4,peerleaf,edge label={node[midway,right] {1}}]
      ]
    ]
    [{},grow=east,peer,edge label={node[midway,right] {1}} 
      [{},grow=east,peer,edge label={node[midway,left] {0}}
        [{},grow=east,draw=c1,fill=c1,peerleaf,edge label={node[midway,left] {0}}]
        [{},grow=east,unused,edge label={node[midway,right] {1}}]
      ]
      [{},grow=east,peer,edge label={node[midway,right] {1}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c2,fill=c2,peerleaf,edge label={node[midway,right] {1}}]
      ]
    ] 
  ]
  [{},grow=east,grow=east,peer,edge label={node[midway,right] {1}}
    [{},grow=east,peer,edge label={node[midway,left] {0}}
      [{},grow=east,peer,edge label={node[midway,left] {0}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c6,fill=c6,peerleaf,edge label={node[midway,right] {1}}]
      ]
      [{},grow=east,peer,edge label={node[midway,right] {1}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,draw=c7,fill=c7,peerleaf,edge label={node[midway,right] {1}}]
      ]
    ]
    [{},grow=east,unused,edge label={node[midway,right] {1}} 
      [{},grow=east,unused,edge label={node[midway,left] {0}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,unused,edge label={node[midway,right] {1}}]
      ]
      [{},grow=east,unused,edge label={node[midway,right] {1}}
        [{},grow=east,unused,edge label={node[midway,left] {0}}]
        [{},grow=east,unused,edge label={node[midway,right] {1}}]
      ]
    ]
  ] 
]
\end{forest}
}

4 Answers 4

6

Thanks Sebastiano.

Using the istgame package:

\documentclass[border=1mm]{standalone}
\usepackage{istgame}

\begin{document}

\begin{istgame}[every node/.style={fill=white,circle,inner sep=0pt,minimum size=5pt}]
\draw (-1,-1.45) --(7.5,-1.45);
\draw (-1,-3.95) --(7.5,-3.95);
\draw (-1,-6.2) --(7.5,-6.2);
%
\setistSolidNodeStyle{10pt}
\setistgrowdirection'{east}
\setistOvalNodeStyle{.8cm}
\xtShowEndPoints[oval node]
%
\xtdistance{25mm}{30mm}
\istrooto(0)<180>{\tiny Root}
\istb<grow=0>[draw=blue]{1}[bl]{}[center]
\istb<grow=-90>[draw=red]{0}[b]{}[center]
 \endist
 %
\xtdistance{20mm}{20mm}
\istrooto(1)(0-1){}
\istb[draw=blue]{1}[bl]{}[center]
\istb{0}[al]{}[center] 
\endist
%
\xtdistance{20mm}{20mm}
\istrooto(2)(1-1){}
\istb{1}[bl]{}[center]
\istb[draw=blue]{0}[al]{}[center] 
\endist
%
 \xtdistance{25mm}{20mm}
\istrooto(3)(0-2)
\istb<grow=14>{1}[bl]{}[center]
\istb<grow=-14>{0}[al]{}[center] 
\istb<grow=-90>[draw=red]{0}[b]{}[center]
 \endist
 %
\xtdistance{20mm}{10mm}
 \istrooto(4)(3-3)
\istb<grow=0>[draw=none]{1}[bl]{}[center]
\istb<grow=-90>[draw=red]{0}[b]{}[center]
 \endist
 %
 \xtTimeLineH[draw=none](0){-8}{0}{root}[font=\small]
 \xtTimeLineH[draw=none](3){-8}{0}{level1}[font=\small]
 \xtTimeLineH[draw=none](4){-8}{0}{level2}[font=\small,yshift=1cm]
 \xtTimeLineH[draw=none](4){-8}{0}{level3}[font=\small,yshift=-1.2cm]
\end{istgame}

\end{document}

Output:

enter image description here

2
  • Welcome and I thank you to have added my name +1.
    – Sebastiano
    Feb 28, 2020 at 7:23
  • 1
    amazing, thanks guys :D Feb 28, 2020 at 10:21
4

I propose another way to draw your first picture using istgame package that for some points of view is similar to forest package. Here there is a starting point and I think that very slowly you can draw your first image.

enter image description here

\documentclass[a4paper,12pt]{article}
\usepackage{xcolor}
\usepackage{istgame}
\usepackage{amssymb}
\begin{document}
\begin{istgame}\setistSolidNodeStyle[blue]{10pt}
\setistgrowdirection'{east}
\setistOvalNodeStyle{.5cm}
\xtShowEndPoints[oval node]
\istrooto(0){}+{10mm}..{5cm}+
\istb[draw=blue]{\textcolor{blue}{1}}[al]
\istb[draw=blue]{\textcolor{blue}{0}}[bl]
\endist
\xtdistance{20mm}{20mm}
\istrooto(1)(0-1){}
\istb[draw=blue]{\textcolor{blue}{1}}[al]{}[center]
\istb[draw=blue]{\textcolor{blue}{0}}[bl]{}[center] 
\endist
\xtdistance{20mm}{20mm}
\istrooto(2)(0-2){}
\istb[draw=blue]{\textcolor{blue}{1}}[al]{}[center]
\istb[draw=blue]{\textcolor{blue}{0}}[bl]{}[center] 
\xtdistance{20mm}{20mm}
\istrooto(3)(1-1){}
\istb[draw=blue]{\textcolor{blue}{1}}[al]{}[center]
\istb[draw=blue]{\textcolor{blue}{0}}[bl]{}[center] 
\endist
\end{istgame}
\end{document}

In this image you can see that the circle can be colored with a specific code.

enter image description here

3

Here's a forest solution. It is neither general nor optimal, but it works. See the comments in the code.

\documentclass{standalone}
\usepackage{forest}
\forestset{
  % The idea is to first generate the tree and then rearrange the nodes.  We
  % need to then set various options for the nodes.  For some it makes sense to
  % set them as soon as the tree is generated, for others it is better to wait
  % until after rearrangement. These two keylists make this process
  % conceptually clean.  (The other option would be to use "delay", but
  % prepending is intertwined with delay cycles, so if we just used "delay", we
  % would need to compute how much delay is needed.)
  declare keylist={after generating tree}{},
  declare keylist={after reordering tree}{},
  typeset nodes stage/.style={
    process keylist=after generating tree,
    process keylist=after reordering tree,
    for root'=typeset nodes,
  },
  generate binary tree/.style={% #1 = number of levels
    if={#1>0}{
      append={[,generate binary tree/.process=n{#1-1}]},
      append={[,generate binary tree/.process=n{#1-1}]},
    }{}
  },
  pull left branches to the root/.style={
    % create an invisible root node first
    replace by={[,append,phantom]},
    % after the new root is created, iteratively prepend the first children to it
    delay={
      if n children={0}{}{for 1=pull left branch to the root},
    },
  },
  pull left branch to the root/.style={
    % a temporary name of the node to be pulled to the root
    alias=pull@temp,
    % pull
    for root={prepend={pull@temp}},
    % iterate
    if n children={0}{}{for 1=pull left branch to the root},
  },
  % Computes minimal and maximal x --- this is used both for drawing both the
  % horizontal lines and the level labels.  It must be executed on the phantom
  % root after x and y of all nodes were already computed.
  setup x for horizontal dividing line/.style={
    % {>...} below are argument processor expressions (manual 3.13) equivalent
    % to pgfmath "x() + min_x()" and "x() + max_x()".  ".min" and ".max" are
    % aggregate functions (3.14); here we set them loose on descendants (of the root)
    tempdimc/.min={>O2w2+d{x}{min x}{##1+##2}}{descendants},
    tempdimd/.max={>O2w2+d{x}{max x}{##1+##2}}{descendants},
  },
  horizontal dividing line/.style={
    % "y() + max_y()" for the tree of one of 00...00 nodes
    tempdima/.max={>O2w2+d{y}{max y}{##1+##2}}{tree},
    % "y() + min_y()" for the tree of the upper 00...00 node
    for next={tempdimb/.min={>O2w2+d{y}{min y}{##1+##2}}{tree}},
    % find the middle of these
    tempdima+/.register=tempdimb,
    tempdima:=2,
    % and draw the line: \draw (tempdimc,tempdima) -- (tempdimd,tempdima);
    % tempdimc and tempdimd were set by "setup x ..."
    tikz+/.process=R3w3{tempdima}{tempdimc}{tempdimd}{\draw (##2,##1) -- (##3,##1);},
  },
  level label/.style={
    % put the level label at (tempdimd,y)
    % tempdimd was set by "setup x ..."; y is the y position of the node (an option)
    tikz+/.process=ROw2{tempdimd}{y}{\node[anchor=west,font=\tiny] at (##1,##2) {#1};},
  },
}


\begin{document}
\begin{forest}
  generate binary tree=3,
  after generating tree={
    for tree={
      circle, draw,
      % Redefine the edge to the parent so that it is labelled. The label is
      % computed automatically; n = the child number (1 or 2), by compute
      % "n()-1" using the argument processor.
      edge path'/.process=Ow1+nw1{n}{#1-1}{
        (.child anchor) --
        node[fill=white,font=\noexpand\tiny,inner sep=1pt]{#1}
        (!u.parent anchor);
      },
    },
    pull left branches to the root,
    after reordering tree={
      % By using "for root'", we can set options for the phantom root created
      % when reordering the tree.
      for root'={
        % everything, including the phantom root, grows to the east
        for tree={grow=east},
        % widen the vertical gap between the leftmost nodes a bit
        s sep*=2,
        % Cleanly separate the subtrees of the leftmost nodes.
        for children={fit=band},
        % This stuff can only be done once x and y coordinates are known:
        before drawing tree={
          setup x for horizontal dividing line,
          % we walk through the leftmost nodes, top-down 
          for last={
            % the very top gets a special label, and no horizontal divide
            level label=root,
            for preceding siblings={
              % automatically figure out the level: "n'" is the child number,
              % counting from the last child
              level label/.process=Ow+nw{n'}{#1-1}{level #1},
              horizontal dividing line,
              % the vertical lines and zeros between the leftmost nodes
              % we'll use the "x" coordinate of the node, and "tempdima" is the
              % register holding "y" of the horizontal divide line we had just
              % drawn.
              tikz+/.process=ORw2{x}{tempdima}{
                % line from this node to the upper one (n=next)
                \draw[red] () -- (!n);
                % at (x,tempdima)
                \node[font=\tiny,fill=white,inner sep=1pt] at (#1,#2) {0};
              },
            }
          }
        }
      },
    },
  },
  % This is the starting tree :-)
  []
\end{forest}\hspace{2em}

\end{document}

the tree

2

Another try of using the istgame package:

enter image description here

\documentclass[border=2pt]{standalone}

\usepackage{istgame}

% not sure about these colours!
\definecolor{c1}{HTML}{FF7F00}
\definecolor{c2}{HTML}{048BA8}
\definecolor{c3}{HTML}{16DB93}
\definecolor{c4}{HTML}{EFEA5A}
\definecolor{c5}{HTML}{F29E4C}
\definecolor{c6}{HTML}{256EFF}
\definecolor{c7}{HTML}{46237A}

\begin{document}
    
\begin{istgame}[draw=blue,text=blue,font=\sffamily\scriptsize]
\tikzset{every node/.style={fill=white}} % action labels with white background
\tikzset{every ellipse node/.style={circle,draw=blue,minimum size=2em}}
\tikzset{xx/.style={circle,draw,fill,minimum size=2em}} % for colored terminal nodes
\setistmathTF*000{sffamily}
\setistgrowdirection'{east}
\xtShowEndPoints[oval node]
\def\xdist{50mm}
%% root
\istrooto(A){Root}
  \istb<grow=0,level distance=.4*\xdist>{1}
  \istb<grow=-90,level distance=.7*\xdist>{0}[pos=.7]
  \endist
\xtdistance{.4*\xdist}{.4*\xdist}
\istrooto(Aa)(A-1)
  \istb{1}
  \istb{0}
  \endist
\xtdistance{.4*\xdist}{.2*\xdist}
\istrooto(Ab)(Aa-1)
  \istb{1}
  \istb{0}
  \endist
\istrooto(Ac)(Aa-2)
  \istb{1}
  \istb{0}
  \endist
%% level 1
\istrooto(0)(A-2)
  \istb<grow=0,level distance=.4*\xdist>{1}
  \istb<grow=-90,level distance=.4*\xdist>{0}[pos=.6]
  \endist
\xtdistance{.4*\xdist}{.2*\xdist}
\istrooto(0a)(0-1)
  \istb{1}{c4}[[xx,c4,text=black]center] % c4
  \istb{0}{}[[xx,c3]center]              % c3
  \endist
%% level 2 & level 3
%\xtdistance{.4*\xdist}{.4*\xdist}
\istrooto(00)(0-2)
  \istb<grow=0,level distance=.4*\xdist>{1}{}[[xx,c2]center]    % c2
  \istb<grow=-90,level distance=.35*\xdist>{0}{}[[xx,c1]center] % c1
  \endist
%% level lines
\coordinate(X0)at($(A)!.65!(0)$);
\coordinate(X1)at($(0)!.57!(00)$);
\coordinate(X2)at($(00)!.5!(00-2)$);
\xtTimeLineH'[solid](X0){1}{-8}%{level 1}[r]
\xtTimeLineH'[solid](X1){1}{-8}%{level 2}[r]
\xtTimeLineH'[solid](X2){1}{-8}%{level 3}[r]
%% level texts
\xtTimeLineH'[draw=none](A){1}{-8}{root}[r]
\xtTimeLineH'[draw=none](0){1}{-8}{level 1}[r]
\xtTimeLineH'[draw=none](00){1}{-8}{level 2}[r]
\xtTimeLineH'[draw=none](00-2){1}{-8}{level 3}[r]
\end{istgame}

\end{document}
4
  • 1
    I like very much your package...but for my experiences it is laborious :-(
    – Sebastiano
    Aug 5, 2020 at 11:36
  • 1
    @Sebastiano Thank you for your kind interest in the istgame package. The main purpose of writing this package was to draw all the game trees in Osbornes book: Introduction to Game Theory. From my point of view, game trees in this book are of standard expression of game trees. In that sense, I believe that istgame is not that difficult (actually simple) to use in drawing game trees, at least those of Osborne's book.
    – InSung Cho
    Aug 5, 2020 at 12:28
  • 1
    @Sebastiano I just added other functions (that I do not use) to draw special shapes of game trees, which may cause some efforts to draw them. Still I guess it is always laborious to draw those special kinds of game trees whichever package is used. One more thing: since one can use the istgame environment just like using the tikzpicture environment, any knowledge of tikz is useful to use istgame.
    – InSung Cho
    Aug 5, 2020 at 12:29
  • 1
    I thank you so much for your long comments. I will now download the new manual that I will read. I always give you my best compliments. And I hope one day to learn a little bit about this package; I TikZ I abandoned it a bit. I like symbols and fonts since I was a child :-)
    – Sebastiano
    Aug 5, 2020 at 12:35

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.