森、枝の非対称

森、枝の非対称

ゴンサロ・メディナの質問に対する回答を検討するTikZ の決定木私の学習プロセスでは、これを少し変更しました。

\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}

ノードにテストを追加すると、なぜ決定木はノードを通る水平対称線に関して非対称になるのでしょうか? たとえば、ノード B では、次のレベルの上位ブランチは、下位ブランチよりもノードを通る中心の水平線からの距離が小さくなります。私はこれを forest 2.0 でテストしました。

ここに画像の説明を入力してください

答え1

これは解決策です。 の値はanchorノードに兄弟がある場合にのみ重要というのは真実ではないため、ドキュメントはかなり誤解を招きます。

[ただし、この回答の以前のバージョンで主張したことは述べられていません。したがって、それを読むと、私は馬鹿なので無視してください。]

のデフォルト値はcaligncenter、親の をanchor​​子の の中点に揃えますanchor。 のデフォルト値はanchorですbase

ここに写真があります:

デフォルトの配置デモ

anchorしたがって、必要な配置を実現するには、親と子の を変更するか、 にデフォルト以外の値を使用する必要がありますcalign

最初のケースでは、anchor=centerツリーの設定として次のようにすることができます。

アンカー=中央

またはanchor=parent(つまりwestこの場合は):

アンカー=親

またはanchor=children(つまりeast)ここ:

アンカー=子

アンカーはchildren常にノードの子 (または子が存在する場所) を向き、parentノードの親 (または親が存在する場所) を向きます。

あるいは、 を変更することもできますcalign。たとえば、 ですcalign=edge midpoint。ただし、これは期待どおりには動作しません。

エッジの中点を揃える

この場合、子の子アンカーがどこにあるか正確にはわかりませんが、コンパイル元またはコンパイル先を基準として、TikZ がパスを取る場所にあるようです。

しかし、ツリーに と を設定しても、実際には役に立ちませんparent anchor=eastchild anchor=west

エッジの中点を揃えますか?

anchorしたがって、他に何が望ましいかに関係なく、以下のようにツリーを変更します。この場合、これで良い結果が得られるようです。

(ただし、非円形ノードの場合は、それ以外のものcenterが意味をなす場合がよくあります。)

他にも、興味があるかもしれない (または興味がないかもしれない) 小さな変更をいくつか加えました。特に、アンカーが方向に依存しないように変更しました。そのため、成長の方向を変更しても、parentアンカーchildは意味をなすはずです。また、パッケージに、端のラベルを線の上または下のどちらに配置するかを判断させました。

だけ

    anchor=children,% work around alignment issue

結果に本当に違いは生じません。

\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}

配置の問題を回避する

デモ用のコード:

\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}

関連情報