我需要将“验证评级”指向训练的箭头置于中心。我还需要使从“训练”指向“拟合模型”的箭头接触该框。最后但并非最不重要的是,我想在“训练验证”框下方添加第二个矩形,上面写着“训练测试”
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{positioning,fit}
\usepackage{lmodern}
\makeatletter
\pgfkeys{/pgf/.cd, % from https://tex.stackexchange.com/a/12039/121799
parallelepiped offset x/.initial=2mm,
parallelepiped offset y/.initial=2mm
}
\pgfdeclareshape{parallelepiped}
{
\inheritsavedanchors[from=rectangle] % this is nearly a rectangle
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid west}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{south east}
\backgroundpath{
% store lower right in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/parallelepiped offset x}}
\pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/parallelepiped offset y}}
\def\ppd@offset{\pgfpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}}
\pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
\pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
\pgfpathclose
\pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@ya}}{\ppd@offset}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\ppd@offset}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xa}{\pgf@yb}}{\ppd@offset}}
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
\pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\ppd@offset}}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[standard/.style={minimum width=3cm,draw,align=center},
font=\tiny]
\begin{scope}[local bounding box=boxes]
\node[standard,minimum height=4cm] (TS) {Training \\ ratings};
\node[standard,below=-\pgflinewidth\space of TS] (VS) {Validation \\ ratings};
\node[standard,below=-\pgflinewidth\space of VS] (TeS) {Test ratings};
\path (TeS.south west) -- (TS.north west) node[midway,left]{Users};
\path (TS.north west) -- (TS.north east) node[midway,above]{Products};
\node[right=1.5cm of TeS.north east,standard] (T1) {Training};
\node[right=-\pgflinewidth\space of T1,standard,minimum width=1cm] (TT1) {Validation};
\node[above=1.5cm of T1,standard] (T2) {Training};
\node[right=-\pgflinewidth\space of T2,standard,minimum width=1cm] (TT2){0};
\node[above=1.5cm of T2,align=center,inner
xsep=1.5em] (PE) {Fit\\ Model};
\node[yscale=1.1,parallelepiped,draw,fit=(PE),inner sep=0pt]{};
\node[right=3cm of PE,standard] (PR) {Ped ratings};
\node[below=1cm of PR,standard,rounded corners=1em] (CEM) {Evaluation \\ metrics};
\end{scope}
\begin{scope}[-latex,thick]
\draw (VS.east) -- (T1.west);
\draw (T1) -- (T2) node[midway,right]{Hide validation ratings};
\draw[shorten >=1mm] (T2) -- (PE) node[midway,right]{Feed Model};
\draw[shorten <=1mm] (PE) -- (PR);
\draw (PR) -- (CEM);
\draw[rounded corners] (TT1.east) -- ++ (2em,0) |- (CEM);
\end{scope}
\begin{scope}[nodes={text width=3.5cm,align=center}]
\node[below] at (boxes.south-|TS) {Bablabla.};
\node[below] at ([xshift=5mm]T1|-boxes.south) {Blablablba};
\node[below] at (CEM|-boxes.south) {Blablablba};
\end{scope}
\end{tikzpicture}
\end{document}
答案1
出于某种原因,这段代码对我来说看起来很熟悉。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{positioning,fit,calc}
\usepackage{lmodern}
\makeatletter
\pgfkeys{/pgf/.cd, % from https://tex.stackexchange.com/a/12039/121799
parallelepiped offset x/.initial=2mm,
parallelepiped offset y/.initial=2mm
}
\pgfdeclareshape{parallelepiped}
{
\inheritsavedanchors[from=rectangle] % this is nearly a rectangle
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid west}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{south east}
\backgroundpath{
% store lower right in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/parallelepiped offset x}}
\pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/parallelepiped offset y}}
\def\ppd@offset{\pgfpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}}
\pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
\pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
\pgfpathclose
\pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@ya}}{\ppd@offset}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\ppd@offset}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xa}{\pgf@yb}}{\ppd@offset}}
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
\pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\ppd@offset}}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[standard/.style={minimum width=3cm,minimum height=1.11em,draw,align=center},
font=\tiny]
\begin{scope}[local bounding box=boxes]
\node[standard,minimum height=4cm] (TS) {Training \\ ratings};
\node[standard,below=-\pgflinewidth\space of TS] (VS) {Validation \\ ratings};
\node[standard,below=-\pgflinewidth\space of VS] (TeS) {Test ratings};
\path (TeS.south west) -- (TS.north west) node[midway,left]{Users};
\path (TS.north west) -- (TS.north east) node[midway,above]{Products};
\node[right=1.5cm of VS,standard] (T1) {Training};
\node[right=-\pgflinewidth\space of T1,standard,minimum width=1cm] (TT1) {Validation};
\node[right=1.5cm of TeS,standard] (T3) {Training};
\path let \p1=($(TT1.north east)-(TT1.south west)$) in
node[right=-\pgflinewidth\space of T3,standard,minimum width=\x1] (TT3) {Test};
\node[above=1.5cm of T1,standard] (T2) {Training};
\path let \p1=($(TT1.north east)-(TT1.south west)$) in
node[right=-\pgflinewidth\space of T2,standard,minimum width=\x1] (TT2){0};
\node[above=1.5cm of T2,align=center,inner
xsep=1.5em,inner ysep=1mm] (PE) {Fit\\ Model};
\node[parallelepiped,draw,fit=(PE),inner sep=0pt](PEF){};
\node[right=3cm of PE,standard] (PR) {Ped ratings};
\node[below=1cm of PR,standard,rounded corners=1em] (CEM) {Evaluation \\ metrics};
\end{scope}
\begin{scope}[-latex,thick]
\draw (VS.east) -- (T1.west);
\draw (TeS.east) -- (T3.west);
\draw (T1) -- (T2) node[midway,right]{Hide validation ratings};
\draw[shorten >=1mm] (T2) -- ([yshift=1mm]PEF.south) node[midway,right]{Feed Model};
\draw[shorten <=1mm] (PE) -- (PR);
\draw (PR) -- (CEM);
\draw[rounded corners] (TT1.east) -- ++ (2em,0) |- (CEM);
\draw[rounded corners] (TT3.east) -- ++ (2em,0) |- (CEM);
\end{scope}
\begin{scope}[nodes={text width=3.5cm,align=center}]
\node[below] at (boxes.south-|TS) {Bablabla.};
\node[below] at ([xshift=5mm]T1|-boxes.south) {Blablablba};
\node[below] at (CEM|-boxes.south) {Blablablba};
\end{scope}
\end{tikzpicture}
\end{document}
附录:这是对 Zarko 帖子的扩展评论。使用的想法append after command
很好,如果不是因为 里面有一条路径\pgfextra
,我会给 +1,pgfmanual 对此进行了说明
请注意,此操作仅应由真正的专家使用,并且仅应在巧妙的宏内部深处使用,而不能在正常路径上使用。
没有必要这样做。您甚至可以使用append after command
来定义样式poor mans parallelepiped
(并使用 避免硬编码距离calc
)。它被称为“穷人的平行六面体”,因为它没有形状的锚点这个答案有。请注意,为了使用这种风格,您需要说明\draw node[poor mans parallelepiped,...] ...
while\node[poor mans parallelepiped,...] ...
不起作用。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{positioning,fit,calc}
\usepackage{lmodern}
\begin{document}
\begin{tikzpicture}[standard/.style={minimum width=3cm,minimum height=1.11em,draw,align=center},
poor mans parallelepiped/.style={standard,append after command={%
let \p1=($(\tikzlastnode.north east)-(\tikzlastnode.south west)$) in
(\tikzlastnode.north west) -- ++ (30:0.3) -- ++ (\x1,0)
-- (\tikzlastnode.north east)
(\tikzlastnode.south east) -- ++ (30:0.3) -- ++(0,\y1) }},
font=\tiny]
\begin{scope}[local bounding box=boxes]
\node[standard,minimum height=4cm] (TS) {Training \\ ratings};
\node[standard,below=-\pgflinewidth\space of TS] (VS) {Validation \\ ratings};
\node[standard,below=-\pgflinewidth\space of VS] (TeS) {Test ratings};
\path (TeS.south west) -- (TS.north west) node[midway,left]{Users};
\path (TS.north west) -- (TS.north east) node[midway,above]{Products};
\node[right=1.5cm of VS,standard] (T1) {Training};
\node[right=-\pgflinewidth\space of T1,standard,minimum width=1cm] (TT1) {Validation};
\node[right=1.5cm of TeS,standard] (T3) {Training};
\path let \p1=($(TT1.north east)-(TT1.south west)$) in
node[right=-\pgflinewidth\space of T3,standard,minimum width=\x1] (TT3) {Test};
\node[above=1.5cm of T1,standard] (T2) {Training};
\path let \p1=($(TT1.north east)-(TT1.south west)$) in
node[right=-\pgflinewidth\space of T2,standard,minimum width=\x1] (TT2){0};
\draw node[above=1.5cm of T2,align=center,poor mans parallelepiped] (PE)
{Fit\\ Model};
\node[right=3cm of PE,standard] (PR) {Ped ratings};
\node[below=1cm of PR,standard,rounded corners=1em] (CEM) {Evaluation \\ metrics};
\end{scope}
\begin{scope}[-latex,thick]
\draw (VS.east) -- (T1.west);
\draw (TeS.east) -- (T3.west);
\draw (T1) -- (T2) node[midway,right]{Hide validation ratings};
\draw[shorten >=1mm] (T2) -- ([yshift=1mm]PE.south) node[midway,right]{Feed Model};
\draw[shorten <=1mm] (PE) -- (PR);
\draw (PR) -- (CEM);
\draw[rounded corners] (TT1.east) -- ++ (2em,0) |- (CEM);
\draw[rounded corners] (TT3.east) -- ++ (2em,0) |- (CEM);
\end{scope}
\begin{scope}[nodes={text width=3.5cm,align=center}]
\node[below] at (boxes.south-|TS) {Bablabla.};
\node[below] at ([xshift=5mm]T1|-boxes.south) {Blablablba};
\node[below] at (CEM|-boxes.south) {Blablablba};
\end{scope}
\end{tikzpicture}
\end{document}
答案2
使用 TikZ 库和 时shapes.multipart
,大多是离题的建议:quotes
positioning
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{arrows.meta,
positioning,
quotes,
shapes.multipart}
\usepackage{lmodern}
\newcommand\textbox[2]{%
\parbox[c][#1][c]{\linewidth}{\centering#2}}
\begin{document}
\begin{tikzpicture}[
node distance = 2mm and 11mm,
standard/.style = {draw, minimum width=#1, minimum height=1.11em,
align=center, inner sep=1mm, outer sep=0pt},
standard/.default = 24mm,
mpnv/.style = {rectangle split, rectangle split parts=3,
draw, text width=3cm, align=center},
mpnh/.style = {rectangle split,rectangle split horizontal,
rectangle split parts=2, align=center,
draw},
tw/.style = {text width=#1},
every edge/.style = {draw, semithick, ->},
> = Stealth,
every edge quotes/.style = {font=\scriptsize, align=left, auto=right},
font = \footnotesize\linespread{0.84}\selectfont
]
\node (n1) [mpnv,
label=Products,
label=left:Users,
label=below:bla bla bla]
{
\nodepart{one} \textbox{4cm}{Training\\
ratings}
\nodepart{two} Validation\\ ratings
\nodepart{three} Test ratings
};
\node (t1) [mpnh, right=of n1.three east,
label=below: blablablabla]
{\nodepart[tw=13mm]{one} Training
\nodepart[tw=15mm]{two} Test
};
\node (t2) [mpnh, right=of n1.two east]
{\nodepart[tw=13mm]{one} Training
\nodepart[tw=15mm]{two} Validation
};
\node (t3) [mpnh, right=of n1.one east]
{\nodepart[tw=13mm]{one} Training
\nodepart[tw=15mm]{two} 0
};
\draw[line join=round]
node (t4) [standard=12mm, below=of n1.north -| t3.one north,
append after command={\pgfextra{\let\LN\tikzlastnode}
(\LN.north west) -- ++ (30:0.3)-- ++ (12mm,0) coordinate (aux)
-- (\LN.north east)
(\LN.south east) -- ++ (30:0.3) -- (aux)
}] {Fit\\ Model};
\node (pr) [standard,
right=of t4 -| t3.east] {Ped ratings};
\node (em) [standard,rounded corners=1em,
above=of t3-| pr] {Evaluation \\ metrics};
\node[below=of t1-| em] {Bla bla blabla};
%
\draw (n1.three east) edge (t1)
(n1.two east) edge (t2)
(t2.one north) edge["Hide\\ validation\\ ratings"] (t3.one south)
(t3.one north) edge["Feed\\ Model"] (t4)
(pr) edge (em);
\draw[shorten <=1mm] (t4) edge (pr);
\draw[rounded corners,->] (t1.east) -- ++ (6mm,0) |- (em);
\draw[rounded corners,->] (t2.east) -- ++ (6mm,0) |- (em);
\end{tikzpicture}
\end{document}