![TikZ 锚定和相对定位](https://linux22.com/image/435046/TikZ%20%E9%94%9A%E5%AE%9A%E5%92%8C%E7%9B%B8%E5%AF%B9%E5%AE%9A%E4%BD%8D.png)
我编写了一个小的 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}