# How can I draw this graph with TikZ or forest?

I want to replicate the structure of the picture below. I don't want to replicate the appearance.

This LaTeX code

\documentclass[tikz,convert={size=640},multi]{standalone}
\usetikzlibrary{graphs,positioning}
\usepackage{forest}
\forestset{
default preamble={
grow=west,
for tree={
parent anchor=children,
child anchor=east,
anchor=east,
draw
}
}
}
\begin{document}
\begin{forest}
[Acceleration
[Map] [Destination] [Vector] [Location]
[{Kind(Street signs, cars, people,...)},name=kind] [Distance,name=distance]]
\graph {
Pixel -- Line -- Shape[left=of kind.west] -- {(distance.west),(kind.west)}
};
\end{forest}
\begin{tikzpicture}
\graph[grow left,left anchor=west,right anchor=east] {
Acceleration[anchor=west] --
{Map[anchor=east], Destination[anchor=east], Vector[anchor=east],
Location[anchor=east],
{{Kind/{Kind(Street signs, cars, people,...)}[anchor=east],
Distance[anchor=east]} -- Shape[anchor=east]}}
};
\end{tikzpicture}
\end{document}
%%% Local Variables:
%%% TeX-command-extra-options: "-shell-escape"
%%% mode: latex
%%% TeX-master: t
%%% End:


renders the two pictures below.

What did I do wrong? How can I fix the pictures?

• Since it is a mindmap and you want "to reproduce the structure and not the appearance", why not use the mindmap tikz library ? – DRi May 19 '16 at 7:05
• @DRi As you saw, I manually drew lines on the picture. It could be either a limitation of the mindmap software or my lack of knowledge, but I'll definitely check mindmap tikz library. – crocket May 19 '16 at 7:39
• @croket There is detailed tutorial on mindmap in the TikZ manual and also many examples in this forum. I got your point that the trick lies in linking the two "centers" Acceleration and Pixel through common branches or nodes, but I got no ideas so far. – DRi May 19 '16 at 7:55

## 3 Answers

It isn't entirely clear what you mean by 'structure'. Normally, for a graph or tree, I'd understand this to mean the way in which the nodes are connected to each other and not the distance and direction of one node relative to another. But it seems you mean the latter as well, although whether this is really it is another matter.

If so, I take it you want something like this:

This is not hard to do in forest. It is just a bit fiddly:

\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{forest}
\forestset{
default preamble={
for tree={
grow=west,
parent anchor=children,
child anchor=parent,
anchor=east,
draw,
minimum height=4ex
}
}
}
\begin{document}
\begin{forest}
[Acceleration
[Map]
[Destination]
[Vector]
[Location]
[{Kind(Street signs, cars, people,...)}, name=kind, tikz+={%
\draw [\forestoption{edge}] (.parent anchor) -- (shape.child anchor);
}
]
[, phantom
[Shape, before computing xy={%
l+/.wrap pgfmath arg={#1}{width(content("kind"))},
}, name=shape
[Line
[Pixel]
]
]
]
[Distance, before drawing tree={%
x-/.wrap pgfmath arg={#1}{width(content("kind"))-width(content())}
}, edge path'={%
(!u.parent anchor) -- (kind.child anchor |- .child anchor) -- (.child anchor)
}, tikz+={%
\draw [\forestoption{edge}] (.parent anchor) -- (shape.child anchor);
}
]
]
\end{forest}
\end{document}


# EDIT

I have no idea what 'vertical space' you ask in the comments to get rid of. The following code sacrifices structural replication for the sake of what may or may not be the desired appearance.

\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{forest}
\forestset{
default preamble={
for tree={
grow=west,
parent anchor=children,
child anchor=parent,
anchor=east,
draw,
minimum height=4ex
}
}
}
\begin{document}
\begin{forest}
[Acceleration
[Map]
[Destination]
[Vector]
[Location]
[{Kind(Street signs, cars, people,...)}, name=kind
[Shape, before computing xy={%
s/.wrap pgfmath arg={#1}{(-s("!u")+s("!un"))/2},
}, name=shape
[Line
[Pixel]
]
]
]
[Distance, before drawing tree={%
x-/.wrap pgfmath arg={#1}{width(content("kind"))-width(content())}
}, edge path'={%
(!u.parent anchor) -- (kind.child anchor |- .child anchor) -- (.child anchor)
}, tikz+={%
\draw [\forestoption{edge}] (.parent anchor) -- (shape.child anchor);
}
]
]
\end{forest}
\end{document}


• Although I didn't expect the negative space among distance, kind, and acceleration in advance, this is exactly what I had in mind. If the negative space is adjusted, it'd be nearly perfect. – crocket May 19 '16 at 22:34
• No idea what you mean. This replicates the structural layout exactly as far as I can tell - and not just the structure of the connections between nodes, but also their relative directions. As you know, Forest is very customisable, so whatever 'negative space' bothers you, you can surely adjust it according to your desiderata. – cfr May 19 '16 at 22:47
• Yes, I'll definitely try to adjust the negative space. – crocket May 19 '16 at 22:48
• Maybe you don't want phantom and just make Shape a child of Kind. But, as I say, I don't actually know whether you mean this or something else entirely. If you do want that, you are not replicating the structure shown, as I would understand it. But maybe that's not really what you meant. – cfr May 19 '16 at 23:57
• Can I make Shape a child of both Kind and Distance? Or, can I make Kind and Distance children of Shape? That's going to reduce the vertical space between Kind and Distance. – crocket May 19 '16 at 23:59

the problem is indeed the connection between Distance, Kind and Pixel. Since "forest" is really a tree, they cant be connect with forest and we have to use the draw command. Therefore we name some nodes. Decorate as you like.

\documentclass[tikz,convert={size=640},multi]{standalone}
\usepackage{tikz}
\usepackage{forest}
\usetikzlibrary{graphs,positioning}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{arrows}

\begin{document}

\begin{forest}
for descendants={anchor=east, child anchor=east, grow=west},
grow=west, anchor=north, parent anchor=north
[Acceleration, rotate=90
[Map]
[Destination]
[Vector]
[Location]
[ [Kind {\tiny (street signs, cars, people)},name=Kind [Pixel, name=Pixel]]
[Distance, name= Distance]]]
\draw[->] (Kind) to[out=west,in=east] (Pixel);
\draw[->] (Distance) to[out=west,in=south east] (Pixel);
\end{forest}
\end{document}

• This is almost there, but it lacks consistency in appearance. How can visual consistency be improved? – crocket May 19 '16 at 21:09
• But you wrote in your question: " I don't want to replicate the appearance." What do you mean by appearance now? Keep in mind that every adjustment of distances in absolute values is working in very simple structures but drives you crazy in normal layouts or if you come back after some time to add or fix something. – Coliban May 20 '16 at 4:11
• I failed to be accurate. I tried to say I didn't want to make a carbon copy of the picture. You can refer to cfr's answer for more information. – crocket May 20 '16 at 4:20

If in your forest version includes grow=west inside for tree options, the result is:

\documentclass[tikz,convert={size=640},multi]{standalone}
\usetikzlibrary{graphs,positioning}
\usepackage{forest}
\forestset{
default preamble={
for tree={
grow=west,
parent anchor=children,
child anchor=east,
anchor=east,
draw
}
}
}
\begin{document}
\begin{forest}
[Acceleration
[Map] [Destination] [Vector] [Location]
[{Kind(Street signs, cars, people,...)},name=kind]
[Distance,name=distance
[Shape [Line [Pixel]]]]]
\end{forest}
\end{document}


Update: Now with shape and kind manually connected

\documentclass[tikz,convert={size=640},multi]{standalone}
\usetikzlibrary{graphs,positioning}
\usepackage{forest}
\forestset{
default preamble={
for tree={
grow=west,
parent anchor=children,
child anchor=east,
anchor=east,
%draw
}
}
}
\begin{document}
\begin{forest}
[Acceleration
[Map] [Destination] [Vector] [Location]
[{Kind(Street signs, cars, people,...)},name=kind]
[Distance,name=distance
[Shape, name=shape [Line [Pixel]]]]]
\draw (shape.north)--++(90:1mm)-|([shift={(5mm,0mm)}]kind.south west);
\end{forest}
\end{document}

• Shape needs to be connected to Distance and kind as in the first picture of my question. – crocket May 19 '16 at 7:07
• @crocket: Did it! – Ignasi May 19 '16 at 10:35
• I'm sorry that I wasn't more accurate when I said I wanted to replicate the structure of the picture. To be more accurate, I want to closely replicate the positions of nodes relative to other nodes. In particular, I want to replicate the relative positions among Shape, Kind, and Distance. – crocket May 19 '16 at 21:07