Considere respuesta de Gonzalo Medina a preguntaárboles de decisión en TikZ. Para mi propuesta de proceso de aprendizaje lo modifiqué ligeramente:
\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 qué el árbol de decisión se vuelve asimétrico con respecto a la línea de simetría horizontal que pasa por los nodos, si agrego alguna prueba en los nodos? Por ejemplo, en el nodo B, las ramas superiores del siguiente nivel tienen una distancia menor desde la línea horizontal central a través del nodo que la inferior. Probé esto con Forest 2.0.
Respuesta1
Esta es una solución. La documentación es bastante engañosa ya que no es cierto que el valor de anchor
solo importa cuando el nodo tiene un hermano.
[Sin embargo, no dice lo que afirmaba mi versión anterior de esta respuesta. Entonces, si lees eso, estaba siendo un idiota y deberías ignorarlo.]
El valor predeterminado de calign
es center
el que alinea el de los padres anchor
con el punto medio entre los de los hijos anchor
. Y el valor predeterminado de anchor
es base
.
Aquí hay una foto:
Entonces, la alineación que nos gustaría requiere cambiar el anchor
valor principal y secundario o usar un valor no predeterminado para calign
.
En el primer caso, podríamos hacer algo como esto, configurando anchor=center
para el árbol:
o anchor=parent
(es decir, west
en este caso):
o anchor=children
(es decir east
) aquí:
El ancla children
siempre mira hacia los hijos del nodo (o hacia donde estarían los hijos); parent
mira al padre del nodo (o donde estaría el padre).
Alternativamente, podríamos alterar calign
. Por ejemplo calign=edge midpoint
. Sin embargo, esto no funciona como esperaba:
No puedo entender exactamente dónde están los anclajes infantiles de los niños en este caso, pero parecen estar dondequiera que TikZ tomaría un camino en relación con el lugar desde donde vienes o hacia dónde vas.
Pero incluso configurar parent anchor=east
y child anchor=west
para el árbol realmente no ayuda:
Así que cambiaría anchor
por el árbol, como hago a continuación, independientemente de lo que parezca deseable. Esto parece dar buenos resultados en este caso.
(Sin embargo, para nodos no circulares, algo distinto center
suele tener sentido).
También hice un par de otras pequeñas modificaciones que pueden interesarle (o no). En particular, cambié los anclajes para que no dependan de la dirección. Entonces puedes cambiar la dirección del crecimiento y los parent
anclajes child
y aún deberían tener sentido. También le pedí al paquete que determinara si las etiquetas en los bordes debían ir por encima o por debajo de las líneas.
Pero sólo
anchor=children,% work around alignment issue
realmente está marcando alguna diferencia en el 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 demostraciones:
\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}