Floresta, assimetria de galhos

Floresta, assimetria de galhos

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.

insira a descrição da imagem aqui

Responder1

Esta é uma solução. A documentação é um tanto enganosa, pois não é verdade que o valor de anchorsó 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é centeraquele que alinha o pai anchorcom o ponto médio entre o s dos filhos anchor. E o valor padrão de anchoré base.

Aqui está uma foto:

demonstração de alinhamento padrão

Portanto, o alinhamento que gostaríamos requer a alteração do anchorpai 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=centerpara a árvore:

âncora = centro

ou anchor=parent(ou seja, westneste caso):

âncora = pai

ou anchor=children(ou seja east) aqui:

âncora=filhos

A âncora childrensempre fica voltada para os filhos do nó (ou onde os filhos estariam); parentenfrenta 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:

alinhar pontos médios das bordas

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=easte child anchor=westpara a árvore realmente não ajuda:

alinhar os pontos médios das arestas?

Então eu mudaria anchorpara 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 centergeralmente 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 childe 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}

problema de alinhamento de solução alternativa

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}

informação relacionada