Considere a resposta de Gonzalo Medina à questãoárvores de decisão em TikZ. Para o meu processo de aprendizagem, modifiquei-o ligeiramente:
\documentclass[tikz,multi,border=5pt]{standalone}
\usepackage{forest}
\tikzset{
EL/.style={%Edge Labels
midway,
#1,% <--- position: "EL=above" or "EL=below"
font=\scriptsize\sffamily,
text=teal,
text width=1.5cm,
align=center,
}
}
\begin{document}
%%%% modified version
\begin{forest}
for tree={
grow=east,
draw=teal,
circle,
line width=0.4pt,
parent anchor=east,
child anchor=west,
edge={draw=teal,very thin},
% edge label={\Huge\color{black}}, % <-- this seems to haven't any influence on tree
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) --
([xshift=-17mm].child anchor) -- % intermediate point
(.child anchor)\forestoption{edge label};
},
l sep=19mm, % <-- *l*: level distance
}
[,rectangle,
s sep=8mm, % <-- *s*: sibling distance
[,edge label={node[EL=below]{option1}}
[,edge label={node[EL=below]{a longer text goes here}}
]
[,edge label={node[EL=above]{text}}
]
]
[B,edge label={node[EL=above]{option2}}
[,edge label={node[EL=below]{a longer text goes here}}
]
[,edge label={node[EL=above]{text}}
]
]
]
\end{forest}
\end{document}
Por que a árvore de decisão se torna assimétrica em relação à linha de simetria horizontal através dos nós, se eu adicionar algum teste nos nós? Por exemplo, no nó B, os ramos superiores do próximo nível têm uma distância menor da linha horizontal central através do nó do que os ramos inferiores. Eu testei isso com a floresta 2.0.
Responder1
Esta é uma solução. A documentação é um tanto enganosa, pois não é verdade que o valor de anchor
só importa quando o nó tem um irmão.
[No entanto, não está dizendo o que minha versão anterior desta resposta afirmava. Então, se você leu isso, eu estava sendo um idiota e você deveria ignorar.]
O valor padrão de calign
é center
aquele que alinha o pai anchor
com o ponto médio entre o s dos filhos anchor
. E o valor padrão de anchor
é base
.
Aqui está uma foto:
Portanto, o alinhamento que gostaríamos requer a alteração do anchor
pai e dos filhos ou o uso de um valor não padrão para calign
.
No primeiro caso, poderíamos fazer algo assim, configurando anchor=center
para a árvore:
ou anchor=parent
(ou seja, west
neste caso):
ou anchor=children
(ou seja east
) aqui:
A âncora children
sempre fica voltada para os filhos do nó (ou onde os filhos estariam); parent
enfrenta o pai do nó (ou onde o pai estaria).
Alternativamente, poderíamos alterar calign
. Por exemplo calign=edge midpoint
. No entanto, isso não funciona exatamente como eu esperava:
Não consigo descobrir exatamente onde estão as âncoras infantis das crianças neste caso, mas elas parecem estar onde-TikZ-seguiria-um-caminho em relação a onde você está vindo ou indo.
Mas mesmo definir parent anchor=east
e child anchor=west
para a árvore realmente não ajuda:
Então eu mudaria anchor
para a árvore, como faço abaixo, independentemente do que mais pareça desejável. Isso parece dar bons resultados neste caso.
(No entanto, para nós não circulares, algo diferente center
geralmente faz sentido.)
Também fiz algumas outras pequenas modificações nas quais você pode (ou não) estar interessado. Em particular, mudei as âncoras para que não dependam da direção. Portanto, você pode mudar a direção do crescimento e as parent
âncoras child
e ainda devem fazer sentido. Também fiz com que o pacote descobrisse se as etiquetas nas bordas deveriam ficar acima ou abaixo das linhas.
Se apenas
anchor=children,% work around alignment issue
está realmente fazendo alguma diferença no resultado.
\documentclass[tikz,multi,border=5pt]{standalone}
\usepackage{forest}
\begin{document}
% Zarko's modification of Gonzalo Medina's answer: http://tex.stackexchange.com/a/177254/
\tikzset{%
EL/.style={%
midway,
#1,
font=\scriptsize\sffamily,
text=teal,
text width=1.5cm,
align=center,
}
}
\begin{forest}
for tree={
draw=teal,
line width=0.4pt,
edge={draw=teal,very thin},
grow=east,
circle,
parent anchor=children,
child anchor=parent,
edge path'={
(!u.parent anchor) -- ([xshift=-17mm].child anchor) -- (.child anchor)
},
l sep=19mm,
anchor=children,% work around alignment issue
},
before typesetting nodes={%
where n=1{%
edge label/.wrap value={node[EL=below]{#1}}
}{%
edge label/.wrap value={node[EL=above]{#1}}
}
}
[, rectangle, s sep=8mm,
[, edge label={option1}
[, edge label={a longer text goes here}
]
[, edge label={text}
]
]
[B, edge label={option2}
[, edge label={a longer text goes here}
]
[, edge label={text}
]
]
]
\end{forest}
\end{document}
Código para demonstrações:
\documentclass[tikz,multi,border=5pt]{standalone}
\usepackage{forest}
\usetikzlibrary{calc}
\begin{document}
\begin{forest}
for tree={% default calign, anchor
grow=east,
draw
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.base) -- (.base);
\draw [densely dotted, red] (.base) -- ($(!1.base)!1/2!(!l.base)$) edge (!1.base) -- (!l.base);
}
[][]
]
]
\end{forest}
\begin{forest}
for tree={% default calign, anchor=center
grow=east,
draw,
anchor=center
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.center) -- (.center);
\draw [densely dotted, red] (.center) -- ($(!1.center)!1/2!(!l.center)$) edge (!1.center) -- (!l.center);
}
[][]
]
]
\end{forest}
\begin{forest}
for tree={% default calign, anchor=parent
grow=east,
draw,
anchor=parent
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.parent) -- (.parent);
\draw [densely dotted, red] (.parent) -- ($(!1.parent)!1/2!(!l.parent)$) edge (!1.parent) -- (!l.parent);
}
[][]
]
]
\end{forest}
\begin{forest}
for tree={% default calign, anchor=children
grow=east,
draw,
anchor=children
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.children) -- (.children);
\draw [densely dotted, red] (.children) -- ($(!1.children)!1/2!(!l.children)$) edge (!1.children) -- (!l.children);
}
[][]
]
]
\end{forest}
\begin{forest}
for tree={% calign=edge midpoint, default anchor
grow=east,
draw,
calign=edge midpoint,
parent anchor=east,
child anchor=west,
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.parent anchor) -- (.child anchor);
\draw [densely dotted, red] (.parent anchor) -- ($(!1.child anchor)!1/2!(!l.child anchor)$) edge (!1.child anchor) -- (!l.child anchor);
}
[][]
]
]
\end{forest}
\end{document}