TikZ 锚定和相对定位

TikZ 锚定和相对定位

我编写了一个小的 tikz 片段,可以按我的预期显示图表

\documentclass{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows}
\usetikzlibrary{positioning}
\begin{document}

\begin{tikzpicture}[node distance=.15cm,>=latex]

\tikzstyle{myarr} = [draw, inner sep=5pt, fill=black!20, single arrow,single arrow head extend=0.1cm]
\tikzstyle{mylbl} = [inner sep=0pt, color=blue!70, text centered, text width=2cm]
\tikzstyle{mybox} = [draw, inner sep=5pt, text centered]

\node[mybox, text depth=2cm, text width=2cm] (corpus) at (0,0) {\textbf{Corpus}};
\node[myarr, single arrow head extend=0cm, single arrow tip angle=130, right=-1cm of corpus] (transformation) {Transformation};

% Is possible to resize the node to fit the whole content?
\node[mybox, text depth=1.75cm, text width=8.5cm, right=-1cm of transformation]  (embedding)  {\textbf{Embedding method}};

% UGLY HACK 1
\node[myarr ,single arrow head extend=0cm,single arrow tip angle=130, rotate=0, right=-1cm of corpus] (transformationhack) {Transformation};

\node[mylbl, right=of transformation] (sentence) {``I think ??? I am''};
\node[myarr, right=of sentence] (arrowa) {};
\node[mybox, minimum height=7ex, right=of arrowa] (cbow) {\textbf{CBOW}};
\node[myarr, right=of cbow] (arrowb) {};
\node[mylbl, right=of arrowb] (predict) {``therefore''};

% Why do I need a larger spacing here?
\node[myarr, rotate=-90, below=.35cm of embedding] (arrowc) {};

% east?
\node[mybox, text width=4cm, text depth=2.5cm, below=of arrowc.east] (embeddings) {\textbf{Word embeddings}};

% How to center this at center of (embeddings) without hand picking.
\node[] at (6.3,-3.80) (matrix) {%
$\begin{bmatrix}
0.12 & 0.59 & \cdots & 0.33 \\
0.48 & 0.02 & \cdots & 0.29 \\
\vdots & \vdots & \ddots & \vdots \\
0.32 & 0.74 & \cdots & 0.61
\end{bmatrix}$
};

\end{tikzpicture}
\end{document}

如下图所示

图表

但我仍然担心我用来实现这些结果的一些“技术”。因此我来这里寻找如何提高代码(和设计)质量的想法。

首先,因为我想让“变换”箭头位于方框上方,所以我绘制了两次,第一次用作第二个方框(嵌入)的标签,第二次绘制在方框上方。我对这种方法感到不舒服。我将其标记为 UGLY HACK。

其次,我尝试使用来打破单词“think”后的节点(句子)\\,但没有成功,为了“修复”这个问题,我强制将文本宽度设置为给定的大小。

第三,如果我添加间距、更改文本或嵌入节点“内部”内容中的任何内容,我需要调整其大小。我知道这是有道理的,但我想知道是否有办法说:看,这些对象在你体内,放大以填充,尊重内部分隔符,优雅一点。

第四,为什么我需要在 (arrowc) 中使用更大的间距,为什么它不尊重全局 .15cm 的距离?

第五,为什么(嵌入)[我知道两个名字非常相似的盒子,抱歉] 盒子需要锚定到(arrowc.east)才能正确放置,为什么不锚定到(arrowc.south)?

最后,我如何将我的(矩阵)节点锚定到“center=of embeddings.center”,而不是手动选择位置?

此致

PS:当然,任何整体的改进都是受欢迎的。

答案1

对于丑陋的黑客 - 只需在两个框都绘制后绘制箭头 - 这样箭头就会覆盖两个框的边框

在此处输入图片描述

\documentclass{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows}
\usetikzlibrary{positioning}
\begin{document}
    
    \begin{tikzpicture}[node distance=.15cm,>=latex]
        
        \tikzstyle{myarr} = [draw, inner sep=5pt, fill=black!20, single arrow,single arrow head extend=0.1cm]
        \tikzstyle{mylbl} = [inner sep=0pt, color=blue!70, text centered, text width=2cm]
        \tikzstyle{mybox} = [draw, inner sep=5pt, text centered]
        
        \node[mybox, text depth=2cm, text width=2cm] (corpus) at (0,0) {\textbf{Corpus}};
        
        % Is possible to resize the node to fit the whole content?
        \node[mybox, text depth=1.75cm, text width=8.5cm, right=1cm of corpus]  (embedding)  {\textbf{Embedding method}};
        \node[myarr, single arrow head extend=0cm, single arrow tip angle=130, right=-1cm of corpus] (transformation) {Transformation};
        
        % UGLY HACK 1
%       \node[myarr ,single arrow head extend=0cm,single arrow tip angle=130, rotate=0, right=-1cm of corpus] (transformationhack) {Transformation};
        
        \node[mylbl, right=of transformation] (sentence) {``I think ??? I am''};
        \node[myarr, right=of sentence] (arrowa) {};
        \node[mybox, minimum height=7ex, right=of arrowa] (cbow) {\textbf{CBOW}};
        \node[myarr, right=of cbow] (arrowb) {};
        \node[mylbl, right=of arrowb] (predict) {``therefore''};
        
        % Why do I need a larger spacing here?
        \node[myarr, rotate=-90, below=.35cm of embedding] (arrowc) {};
        
        % east?
        \node[mybox, text width=4cm, text depth=2.5cm, below=of arrowc.east] (embeddings) {\textbf{Word embeddings}};
        
        % How to center this at center of (embeddings) without hand picking.
        \node[] at (6.3,-3.80) (matrix) {%
            $\begin{bmatrix}
                0.12 & 0.59 & \cdots & 0.33 \\
                0.48 & 0.02 & \cdots & 0.29 \\
                \vdots & \vdots & \ddots & \vdots \\
                0.32 & 0.74 & \cdots & 0.61
            \end{bmatrix}$
        };
        
    \end{tikzpicture}
\end{document}

编辑--句子中断

align=left只需在标签框的定义中使用如下

    \tikzstyle{mylbl} = [inner sep=0pt, color=blue!70, align=left ] 

现在你可以使用\\它来拆分句子——当然对齐会偏离,因为"第一行有一个,但第二行没有,所以你可以phantom "在第二行添加一个,虽然不会打印出来,但会改善对齐。

    \node[mylbl, right=of transformation] (sentence) {``I think \\ \phantom{"}I am''};

在此处输入图片描述

\documentclass{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows}
\usetikzlibrary{positioning}
\begin{document}
    
    \begin{tikzpicture}[node distance=.15cm,>=latex]
        
        \tikzstyle{myarr} = [draw, inner sep=5pt, fill=black!20, single arrow,single arrow head extend=0.1cm]
        \tikzstyle{mylbl} = [inner sep=0pt, color=blue!70, align=left ]
        \tikzstyle{mybox} = [draw, inner sep=5pt, text centered]
        
        \node[mybox, text depth=2cm, text width=2cm] (corpus) at (0,0) {\textbf{Corpus}};
        
        % Is possible to resize the node to fit the whole content?
        \node[mybox, text depth=1.75cm, text width=8.5cm, right=1cm of corpus]  (embedding)  {\textbf{Embedding method}};
        \node[myarr, single arrow head extend=0cm, single arrow tip angle=130, right=-1cm of corpus] (transformation) {Transformation};
        
        % UGLY HACK 1
%       \node[myarr ,single arrow head extend=0cm,single arrow tip angle=130, rotate=0, right=-1cm of corpus] (transformationhack) {Transformation};
        
        \node[mylbl, right=of transformation] (sentence) {``I think \\ \phantom{"}I am''};
        \node[myarr, right=of sentence] (arrowa) {};
        \node[mybox, minimum height=7ex, right=of arrowa] (cbow) {\textbf{CBOW}};
        \node[myarr, right=of cbow] (arrowb) {};
        \node[mylbl, right=of arrowb] (predict) {``therefore''};
        
        % Why do I need a larger spacing here?
        \node[myarr, rotate=-90, below=.35cm of embedding] (arrowc) {};
        
        % east?
        \node[mybox, text width=4cm, text depth=2.5cm, below=of arrowc.east] (embeddings) {\textbf{Word embeddings}};
        
        % How to center this at center of (embeddings) without hand picking.
        \node[] at (6.3,-3.80) (matrix) {%
            $\begin{bmatrix}
                0.12 & 0.59 & \cdots & 0.33 \\
                0.48 & 0.02 & \cdots & 0.29 \\
                \vdots & \vdots & \ddots & \vdots \\
                0.32 & 0.74 & \cdots & 0.61
            \end{bmatrix}$
        };
        
    \end{tikzpicture}
\end{document}

EDIT2——用于扩大节点

使用tikzlibrary{fit}如下

   \node[draw=teal, dashed,ultra thick,  fit=(sentence) (arrowa)(arrowb) (cbow)(predict)] {};

如果你在里面的节点添加任何东西,它将自动放大

在此处输入图片描述

编辑--对于arrowc.east

旋转箭头时锚点也会旋转,因此当旋转 -90 度时,东锚点将取代南锚点

对于矩阵的放置-- 我再次建议使用 fit 库,以便它可以随矩阵扩展

在此处输入图片描述

您的问题与选择节点的位置有关

完成 MWE

\documentclass{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows}
\usetikzlibrary{positioning,fit}
\begin{document}
    
    \begin{tikzpicture}[node distance=.15cm,>=latex]
        
        \tikzstyle{myarr} = [draw, inner sep=5pt, fill=black!20, single arrow,single arrow head extend=0.1cm]
        \tikzstyle{mylbl} = [inner sep=0pt, color=blue!70, align=left ]
        \tikzstyle{mybox} = [draw, inner sep=5pt, text centered]
        
        \node[mybox, text depth=2cm, text width=2cm] (corpus) at (0,0) {\textbf{Corpus}};
        
        % Is possible to resize the node to fit the whole content?
        \node[mybox, draw=none, text depth=1.75cm, text width=8.5cm, right=1cm of corpus]  (embedding)  {\textbf{Embedding method}};
        \node[myarr, single arrow head extend=0cm, single arrow tip angle=130, right=-1cm of corpus] (transformation) {Transformation};
        
        % UGLY HACK 1
%       \node[myarr ,single arrow head extend=0cm,single arrow tip angle=130, rotate=0, right=-1cm of corpus] (transformationhack) {Transformation};
        
        \node[mylbl, right=of transformation] (sentence) {``I think \\ \phantom{"}I am''};
        \node[myarr, right=of sentence] (arrowa) {};
        \node[mybox, minimum height=7ex, right=of arrowa] (cbow) {\textbf{CBOW}};
        \node[myarr, right=of cbow] (arrowb) {};
        \node[mylbl, right=of arrowb] (predict) {``therefore''};
        
        % Why do I need a larger spacing here?
        \node[myarr, rotate=-90, below=of embedding] (arrowc) {};
        
        % east?
        \node[mybox, draw=none,  below=of arrowc.east] (embeddings) {\textbf{Word embeddings}};
        
        % How to center this at center of (embeddings) without hand picking.
        \node[below=2cm of embedding]  (matrix) {%
            $\begin{bmatrix}
                0.12 & 0.59 & \cdots & 0.33 \\
                0.48 & 0.02 & \cdots & 0.29 \\
                \vdots & \vdots & \ddots & \vdots \\
                0.32 & 0.74 & \cdots & 0.61
            \end{bmatrix}$
        };
        \node[draw=teal, dashed,ultra thick,  fit=(matrix)(embeddings)] {};
        \node[draw=teal, dashed,ultra thick,  fit=(sentence) (arrowa)(arrowb) (cbow)(predict)] {};
    \end{tikzpicture}
\end{document}

相关内容