I am trying to draw a randomized tree using TikZ, that is, I'm looking for a macro \randtree{NN}{x}
that attaches a randomized tree of maximum depth x to a node named NN
. The nodes need not be visible or marked, I just want the lines.
I did a bit of research on randomized TikZ pictures, but since I never really used randomization with TikZ before, most of the examples were so complicated that I didn't understand what was going on (e.g. Referring to tikz picture again in the same document)
plus, most randomization examples (at least the ones I found) just randomize the shape of individual lines, wheras I want entire node structures to be randomized.
Here is a (non-random, non-automatic) example of what I'm hoping for:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\newcommand\mytree[1]{
\coordinate[above right=1cm and 1.0cm of #1] (r);
\coordinate[above right=2cm and 2.0cm of r] (rr);
\coordinate[above left =1cm and 0.5cm of r] (rl);
\coordinate[above right=1cm and 1.0cm of rl] (rlr);
\coordinate[above left =1cm and 0.5cm of rl] (rll);
\coordinate[above left =1cm and 1.0cm of #1] (l);
\coordinate[above left =1cm and 1.0cm of l] (ll);
\coordinate[above right=2cm and 0.5cm of l] (lr);
\coordinate[above left =1cm and 1.0cm of lr] (lrl);
\coordinate[above right=1cm and 0.2cm of lr] (lrr);
\coordinate[above left =1cm and 1.0cm of ll] (lll);
\coordinate[above right=1cm and 0.5cm of ll] (llr);
\coordinate[above left =1cm and 1.0cm of rlr] (rlrl);
\draw[black] (lll) -- (ll);
\draw[black] (ll) -- (l);
\draw[black] (l) -- (sv);
\draw[black] (sv) -- (r);
\draw[black] (r) -- (rr);
\draw[black] (r) -- (rl);
\draw[black] (l) -- (lr);
\draw[black] (rl) -- (rll);
\draw[black] (rl) -- (rlr);
\draw[black] (ll) -- (llr);
}
\begin{document}
\begin{tikzpicture}[node distance=1cm and 0.4cm]
\coordinate (sv);
\mytree{sv};
\end{tikzpicture}
\end{document}
It's not required that all branches have the same total height at the end, nor is the absolute number of nodes of any interest. I just want to specify the maximum number of nodes from trunk to leaf, and the total scale of the tree (approximate height and width, both values are allowed to float up or down).
The tree should alway grow from bottom to top, but if that's also customizable, even the better.
A ready-made solution would be too much to ask, so I'll be happy with a simple example or pointers to the appropriate sections of the TikZ manual.
Edit
Following a request from one of the comments, I try to be more clear about what I'm trying to achieve. I'm trying to reproduce the following graphic:
I managed to make most of it on my own, the only thing still missing is the (more-or-less) random decay diagrams on top of the pink blobs (circled in red). Since the precise structure of these things is not of particular importance, nor is the fact that they have arrow tips at their end, I thought that the easiest way to generate them was to create a randomized tree of given size and attach it to the TikZ nodes at the pink blobs.
In the meantime, I opened another question on the same subject, trying to build these decay-chain-structures manually (Drawing recursive randomized structures with TikZ). If you have a solution on how to do this using a tree construct (forest
, tikz-qtree
, …), please answer to this question – if you know a way how to manually create these structures, please anwer the one linked above.
Edit 2
Since I got a nice answer and was able to plug everything together, I figured I might as well make the source code of my picture available to everyone. Enjoy!
Preparation
\usetikzlibrary{positioning,arrows,patterns}
\usetikzlibrary{decorations.pathmorphing}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{decorations.shapes}
\def\pgfdecoratedcontourdistance{0pt}
\pgfkeys{/pgf/decoration/contour distance/.code={%
\pgfmathparse{#1}%
\let\pgfdecoratedcontourdistance=\pgfmathresult}%
}
\pgfdeclaredecoration{contour lineto}{start}
{
\state{start}[next state=draw, width=0pt]{
\pgfpathmoveto{\pgfpoint{0pt}{\pgfdecoratedcontourdistance}}%
}
\state{draw}[next state=draw, width=\pgfdecoratedinputsegmentlength]{
\pgfmathparse{-\pgfdecoratedcontourdistance*cot(-\pgfdecoratedangletonextinputsegment/2+90)}%
\let\shorten=\pgfmathresult%
\pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength+\shorten}{\pgfdecoratedcontourdistance}}%
}
\state{final}{
\pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength}{\pgfdecoratedcontourdistance}}%
}
}
\tikzset{
photon/.style={decorate, decoration={snake}, draw=black},
crossed/.style={draw=black, postaction={decorate},decoration={markings,mark=at position .5 with {\draw (-2pt,-2pt) -- (2pt,2pt);\draw (2pt,-2pt) -- (-2pt,2pt);}}},
fermion/.style={draw=black, postaction={decorate},decoration={markings,mark=at position .55 with {\arrow{>}}}},
weak/.style={dashed, draw=black},
special/.style={decorate,decoration={shape backgrounds,shape=circle,shape size=0.5pt,shape sep=2pt}},
gluon/.style={decorate, draw=black,decoration={coil,amplitude=4pt, segment length=5pt}} ,
hadron/.style={
draw=black,
postaction={
decoration={contour lineto, contour distance=-2pt},
draw=black, decorate},
postaction={
decoration={contour lineto, contour distance=2pt},
draw=black, decorate}
},
meson/.style={
draw=none,
postaction={
decoration={contour lineto, contour distance=-1pt},
draw=black,decorate},
postaction={
decoration={contour lineto, contour distance=1pt},
draw=black, decorate},
},
vertex/.style={draw,shape=circle,fill=black,minimum size=3pt,inner sep=0pt},
bbvertex/.style={draw,shape=circle,pattern=north east lines,very thin,minimum size=12pt,inner sep=0pt}
}
\newcommand{\generateShower}[1]{
\scalebox{.3}{
\pgfmathsetseed{#1}
\begin{forest}
random tree/.style n args={2}{% #1=max levels, #2=max children
if={##1>0}{repeat={random(0,##2)}{append={[,random tree={##1-1}{##2}]}}}{},
parent anchor=center, child anchor=center, grow=north},
[,random tree={3}{3}]
\end{forest}
}
}
Actual picture
\begin{tikzpicture}[node distance=1cm and 0.4cm]
%% the bottom part
\coordinate[vertex] (sv);
\coordinate[vertex, below =1cm and 0.4cm of sv] (pv);
\coordinate[bbvertex, below left =1cm and 0.4cm of pv] (vl);
\coordinate[bbvertex, below right=1cm and 0.4cm of pv] (vr);
\coordinate[ below left =1cm and 0.4cm of vl] (il);
\coordinate[ below right=1cm and 0.4cm of vr] (ir);
\coordinate[ above left =1cm and 0.4cm of vl] (fl);
\coordinate[ above right=1cm and 0.4cm of vr] (fr);
\draw[hadron] (il) -- (vl);
\draw[meson] (vl) -- (fl);
\draw[fermion](vl) -- (pv);
\draw[hadron] (ir) -- (vr);
\draw[meson] (vr) -- (fr);
\draw[fermion](pv) -- (vr);
%% the connecting line
\draw[photon] (pv) -- (sv);
%% the top part
\coordinate[ vertex,above right=2cm and 2.0cm of sv] (r);
\coordinate[ vertex,above left =0.5cm and 0.7cm of r] (rl);
\coordinate[ vertex,above right=0.5cm and 1.0cm of rl] (rlr);
\coordinate[ vertex,above left =0.5cm and 1.0cm of rl] (rll);
\coordinate[ vertex,above left =1cm and 1.0cm of sv] (l);
\coordinate[ vertex,above left =1cm and 1.0cm of l] (ll);
\coordinate[ vertex,above right=2cm and 0.5cm of l] (lr);
\coordinate[bbvertex,above left =1cm and 1.0cm of lr] (lrl);
\coordinate[bbvertex,above right=1cm and 0.2cm of lr] (lrr);
\coordinate[bbvertex,above left =2cm and 2.0cm of ll] (lll);
\coordinate[ vertex,above right=1cm and 0.5cm of ll] (llr);
\coordinate[bbvertex,right=1cm of lrr] (rlrl);
\coordinate[bbvertex,right=2.5cm of rlrl] (rr);
%% tree-level fermion lines
\draw[fermion] (lll) -- (ll);
\draw[fermion] (ll) -- (l);
\draw[fermion] (l) -- (sv);
\draw[fermion] (sv) -- (r);
\draw[fermion] (r) -- (rr);
%% connection gluons
\draw[gluon] (r) -- (rl);
\draw[gluon] (l) -- (lr);
\draw[gluon] (rl) -- (rll);
\draw[gluon] (rl) -- (rlr);
\draw[gluon] (ll) -- (llr);
%% branch-level fermion lines
\draw[fermion] (rr) -- (rlr);
\draw[fermion] (rlr) -- (rlrl);
\draw[fermion] (rlrl) -- (rll);
\draw[fermion] (rll) -- (lrr);
\draw[fermion] (lrr) -- (lr);
\draw[fermion] (lr) -- (lrl);
\draw[fermion] (lr) -- (lrl);
\draw[fermion] (lrl) -- (llr);
\draw[fermion] (llr) -- (lll);
%% decay chains for bb vertices: rr, lrl, lrr, lll, rlrl
\node[yshift=-5.5pt,xshift=-1.5pt,anchor=south] at (lll.north) {\generateShower{33333}};
\node[yshift=-5.5pt,xshift=-3pt,anchor=south] at (lrl.north) {\generateShower{25763}};
\node[yshift=-5.5pt,xshift=2pt,anchor=south] at (lrr.north) {\generateShower{76924}};
\node[yshift=-5.5pt,xshift=-4pt,anchor=south] at (rlrl.north){\generateShower{45678}};
\node[yshift=-5.5pt,xshift=-1.5pt,anchor=south] at (rr.north) {\generateShower{14285}};
%% lhs braces
\draw [decorate,decoration={brace,amplitude=5pt}] (-5,-3.5) -- (-5,-1.5)
node [black,midway,xshift=-0.8cm,left,text width=3cm,align=right] {parton\\distributions};
\draw [decorate,decoration={brace,amplitude=5pt}] (-5.5,-1.5) -- (-5.5,0.5)
node [black,midway,xshift=-0.3cm,left,text width=3cm,align=right] {hard\\scattering};
\draw [decorate,decoration={brace,amplitude=5pt}] (-5,0.4) -- (-5,3.8)
node [black,midway,xshift=-0.8cm,left,text width=3cm,align=right] {parton\\shower};
\draw [decorate,decoration={brace,amplitude=5pt}] (-5.5,3.7) -- (-5.5,4.7)
node [black,midway,xshift=-0.3cm,left,text width=3cm,align=right] {hadronization};
\draw [decorate,decoration={brace,amplitude=5pt}] (-5,4.6) -- (-5,5.7)
node [black,midway,xshift=-0.8cm,left,text width=3cm,align=right] {decay};
\end{tikzpicture}
Best Answer
This is an example modified based on page 1 of the
forest
package documentation.Note the default anchors of the
forest
package is not the center of a node, and thus there appear to be white spaces between edges. To fix this, set bothparent anchor
andchild anchor
tocenter
, so that they can "connect" with each other. Thegrow
key specifies the direction to which the tree should grow. Since you want it to grow upwards,grow=north
would do the trick.Update: Attaching tree to another node
This is probably not the best way to attach a
forest
tree to anothertikz
node, but it's the only thing I can come up with that works.The idea is to put the
forest
tree inside a node, and use node positioning commands to "attach" it to another node. The main imperfection is that you have to manually adjust theyshift
and\scalebox
parameters. (I've tried usinginner sep=0pt
andouter sep=0pt
. But those screwed up theforest
picture.)