TikZ 图形的最佳再现

TikZ 图形的最佳再现

在此处输入图片描述

我对感兴趣适当地重现上图。红色标记不是图的一部分,只是为了识别块。我对以下方面特别感兴趣。

  1. 块 A 的上边框应与块 B1 的上边框高度相同;其下边框应与块 BK 的下边框高度相同。块 C 也是如此。
  2. 区块 A 与区块 Bi (i=1,...,K) 之间的分叉应该如上图所示,即有足够的空间容纳 $\vec p(\vec c)$ 并且呈这种角度形式。
  3. 在块内部,AI 希望在顶部、底部和中间放置文本。
  4. 理想情况下,我可以设置 B2 块和 BK 块之间的距离。

下面是我的尝试。我不喜欢的是:

  • 要求 1 并未完全满足。我必须手动设置块 A 和 C 的高度,但框仍然未对齐(可能高达 的倍数line width)。
  • B2和BK之间的空白区域太多(两个看不见的小节点)。
  • 块 A 内的间距是手工制作的。也许类似的东西$p_1...$\\$p_2...$\vfill$\vdots$\vfill$p_K...$可以完成这项工作。

我的尝试

\documentclass[border=2mm]{standalone}

\usepackage[dvipsnames]{xcolor}
\usepackage{tikz,amsmath}
\usetikzlibrary{positioning}

\begin{document}
   \begin{tikzpicture}[
      node distance=0.2cm and 1.2cm,
      small node/.style={rectangle, draw, minimum width=2.5cm, minimum height=1  cm, align=center, fill=lightgray},
      large node/.style={small node, minimum height=5.8cm},
      invisible node/.style={minimum size=0pt, inner sep=0pt, outer sep=0pt},
   ]
      % Nodes.
      \node[invisible node] (init) {};
      
      \node[large node, right=of init, align=center] (a) {$p_1p(\vec c\vert\Omega_1)$\\$p_2p(\vec c\vert\Omega_2)$\\[1cm]$\vdots$\\[1cm]$p_Kp(\vec c\vert\Omega_K)$};
      
      \node[invisible node, right=of a] (b) {};
      
      \node[small node, right=of b , draw=none, fill=none] (c3) {};
      \node[small node, above=of c3                      ] (c2) {$\vec r_1^\top \vec p(\vec c)$};
      \node[small node, above=of c2,                     ] (c1) {$\vec r_0^\top \vec p(\vec c)$};
      \node[small node, below=of c3, draw=none, fill=none] (c4) {};
      \node[small node, below=of c4                      ] (c5) {$\vec r_K^\top \vec p(\vec c)$};
      
      \node[large node, right=of c3] (d) {$\kappa^\ast = \arg\min_\kappa u_\kappa$};
      
      \node[invisible node, right=of d] (e) {};
      
      
      % Arrows.
      \draw[->] (init) -- node[anchor=south, pos=0.5] {$\vec c$}         (a);
      
      \draw[  ] (a)    -- node[anchor=south, pos=0.5] {$\vec p(\vec c)$} (b);
      
      \draw[->] (b)    |- node[anchor=south, pos=0.5] {}                 (c1);
      \draw[->] (b)    |- node[anchor=south, pos=0.5] {}                 (c2);
      \draw[->] (b)    |- node[anchor=south, pos=0.5] {}                 (c5);
      
      \draw[->] (c1) -- node[anchor=south]{$u_0(\vec c)$} (c1 -| d.west);
      \draw[->] (c2) -- node[anchor=south]{$u_1(\vec c)$} (c2 -| d.west);
      \draw[->] (c5) -- node[anchor=south]{$u_K(\vec c)$} (c5 -| d.west);
      
      \draw[->] (d) -- node[anchor=south] {$\Omega_{\kappa^\ast}$} (e);
   \end{tikzpicture}
\end{document}

答案1

以下是一些想法:

  • 首先绘制中间的框并用作大框的参考(通过ext.positioning-plus和它的部分|和使得新框的总高度等于其他框的高度)。ofleftright

  • 左侧框的内容作为标签或

  • 它们dumb labels与相应的小盒子放置在相同的高度。

  • horizontal vertical horizontal这些线由(即-|-)和绘制only horizontal first

  • 设置各种minimum width要求minimum height,以使节点看起来不那么紧凑,但左侧框也足够宽以容纳其标签。(可以使用自动方法,但这种方法更快。)

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{
  arrows.meta,
  ext.paths.ortho,
  ext.positioning-plus,
  quotes,
}
\tikzset{
  math nodes/.style={execute at begin node=$, execute at end node=$},
  dumb label/.style args={[#1]#2}{label={[{tikz@label@post/.code=,anchor=center,#1}]#2}},
}
\begin{document}
\begin{tikzpicture}[
  every box/.style={draw, fill=lightgray, minimum width=+6em},
  small box/.style={every box, minimum height=+2em},
  big box/.style={every box},
  every label/.append style={align=center},
  node distance=2mm and 4em,
  every edge quotes/.append style=math nodes,
]
\node[small box] (c0)                   {$\vec r_0^\top \vec p(\vec c)$};
\node[small box] (c1) [below=    of c0] {$\vec r_1^\top \vec p(\vec c)$};
\node[small box] (cK) [below=4em of c1] {$\vec r_K^\top \vec p(\vec c)$};
%                            ^^^ vertical distance between c1 and ck
\node[big box] (box1) [left=of |(c0)(cK),
  label={[below]above:$p_1p(\vec c \,\vert \Omega_1)$ \\
                      $p_2p(\vec c\, \vert \Omega_2)$},
  label={[above]below:$p_Kp(\vec c \,\vert \Omega_K)$},
]{$\vdots$};
\node[big box] (box2) [right=of |(c0)(cK)]{$\kappa^\ast = \arg\min_\kappa u_\kappa$};

\path[->] (box1.west) edge[<-, "\vec c"'] +(left:x_node_dist)
          [horizontal vertical horizontal, ortho/ratio=.6666]
          (box1) edge (c0)
                 edge["\vec p(\vec c)" very near start] (c1)
                 edge (cK)
          [only horizontal first]
          (c0) edge["u_0(\vec c)"] (box2)
          (c1) edge["u_1(\vec c)"] (box2)
          (cK) edge["u_\kappa(\vec c)"] (box2)
          [line to] % back to --
          (box2.east) edge["\Omega_{\kappa^\ast}"] +(right:x_node_dist)
;
\end{tikzpicture}
\begin{tikzpicture}[
  every box/.style={draw, fill=lightgray, minimum width=+6em},
  small box/.style={every box, minimum height=+2em},
  big box/.style={every box},
  every label/.append style={align=center},
  node distance=2mm and 4em,
  every edge quotes/.append style=math nodes,
]
\node[small box] (c0)                   {$\vec r_0^\top \vec p(\vec c)$};
\node[small box] (c1) [below=    of c0] {$\vec r_1^\top \vec p(\vec c)$};
\node[small box] (cK) [below=4em of c1] {$\vec r_K^\top \vec p(\vec c)$};
%                            ^^^ vertical distance between c1 and ck
\node[big box] (box1) [left=of |(c0)(cK),
  @/.style={dumb label={[at=(\tikzlastnode|-c#1), name=\tikzlastnode#1]%
    $p_{#1}p(\vec c \,\vert \Omega_{#1})$}},
  @/.list={0, 1, K},
]{};
\path (box11) -- node {$\vdots$} (box1K); % or at ($(box11)!.5!(box1K)$)
\node[big box] (box2) [right=of |(c0)(cK)]{$\kappa^\ast = \arg\min_\kappa u_\kappa$};

\path[->] (box1.west) edge[<-, "\vec c"'] +(left:x_node_dist)
          [horizontal vertical horizontal, ortho/ratio=.6666]
          (box1) edge (c0)
                 edge["\vec p(\vec c)" very near start] (c1)
                 edge (cK)
          [only horizontal first]
          (c0) edge["u_0(\vec c)"] (box2)
          (c1) edge["u_1(\vec c)"] (box2)
          (cK) edge["u_\kappa(\vec c)"] (box2)
          [line to] % back to --
          (box2.east) edge["\Omega_{\kappa^\ast}"] +(right:x_node_dist)
;
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述 在此处输入图片描述

相关内容