考慮以下 MWE:
\documentclass[a4paper]{scrartcl}
\usepackage{mathtools}
\usepackage{amssymb}
\usepackage[compatibility=false]{caption}
\usepackage[list]{subcaption}
\usepackage{fancyvrb}
\usepackage{tikz}
\usetikzlibrary{patterns, fit, positioning, calc, shapes.arrows}
\usepackage[active, tightpage, floats, displaymath]{preview}
\mathtoolsset{%
mathic=true
}
% Vectors and matrices
\renewcommand*{\vec}[1]{\mathbf{#1}}
\newcommand{\mat}[1]{\mathbf{#1}}
\newcommand{\trans}{\intercal}
% Operators
\DeclareMathOperator{\rank}{rank}
\DeclareMathOperator*{\argmin}{arg\,min}
\DeclareMathOperator*{\argmax}{arg\,max}
\begin{document}
\begin{figure}
\centering
\captionsetup[subfigure]{margin={2.5cm, 0cm}}
\begin{subfigure}[b]{0.60\textwidth}
\centering
\begin{tikzpicture}[>=latex, shorten >=2pt, shorten <=2pt]
\node[draw, rectangle, label=below:the] (the) {\(\mat W\)};
\node[draw, rectangle, right=of the, label=below:cat] (cat) {\(\mat W\)};
\node[draw, rectangle, right=of cat, label=below:sat] (sat) {\(\mat W\)};
\node[draw, rectangle, fit=(the.west) (the.east), pattern=vertical lines, above=of the] (in_the) {};
\node[draw, rectangle, fit=(cat.west) (cat.east), pattern=vertical lines, above=of cat] (in_cat) {};
\node[draw, rectangle, fit=(sat.west) (sat.east), pattern=vertical lines, above=of sat] (in_sat) {};
\node[draw, rectangle, fit={($(cat.west) + (-8pt,0pt)$) ($(cat.east) + (8pt,0pt)$)}, pattern=vertical lines, above=2cm of cat] (in) {};
\node[draw, rectangle, above=of in, label=above:mat] (out) {\(\vec b\), \(\mat U\)};
\node[left=of the, outer sep=0] (embed) {embed};
\node[above=2cm of embed, outer sep=0] (concatenate) {concatenate};
\node[above=1cm of concatenate, outer sep=0] {softmax};
\foreach \word in {the, cat, sat}{%
\draw[->] (\word) -- (in_\word);
\draw[->] (in_\word) -- (in);
}
\draw[->] (in) -- (out);
\end{tikzpicture}
\caption{CBOW model}\label{fig:cbow}
\end{subfigure}
\captionsetup[subfigure]{margin={0cm,0cm}}
\begin{subfigure}[b]{0.35\textwidth}
\centering
\begin{tikzpicture}[>=latex, shorten >=2pt, shorten <=2pt]
\node[draw, rectangle, label=below:cat] (cat) {\(\mat W\)};
\node[draw, rectangle, fit=(cat.west) (cat.east), pattern=vertical lines, above=of cat] (in) {};
\node[draw, rectangle, above=2cmof in, label=above:on] (on) {\(\vec b\), \(\mat U\)};
\node[draw, rectangle, left=of on, label=above:sat] (sat) {\(\vec b\), \(\mat U\)};
\node[draw, rectangle, right=of on, label=above:the] (the) {\(\vec b\), \(\mat U\)};
\draw[->] (cat) -- (in);
\foreach \word in {sat, on, the}{%
\draw[->] (in) -- (\word);
}
\end{tikzpicture}
\caption{Skip\=/gram model}\label{fig:sg}
\end{subfigure}
\caption{\protect\Verb+Word2Vec+ with vocabulary size \(V\), context
size \(C\), and embedding size \(N\)}
\end{figure}
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:
哪個排版為:
正如您所看到的,我通過使用“居中”了“(a) CBOW model”標題\captionsetup[subfigure]{margin={2.5cm, 0cm}}
。我的問題是:是否可以不必這樣做?或至少以某種方式計算出我需要偏移標題的正確寬度?
答案1
您可以\useasboundingbox
在 TikZ 中使用來設定圖片的尺寸。然後 TikZ 將忽略該命令之後的所有內容來計算圖片大小。您(current bounding box)
可以參考到目前為止圖片的尺寸。只要您在線條之前繪製所有內容(應計入紙張尺寸),\useasboundingbox (current bounding box)
圖片就會具有所需的尺寸。
此外,還需要一個空白subfigure
以允許向左重疊。所以它必須是第一個。當然,必須調整左側(現在是中間)子圖的寬度。
\documentclass[a4paper]{scrartcl}
\usepackage{mathtools}
\usepackage{amssymb}
\usepackage[compatibility=false]{caption}
\usepackage[list]{subcaption}
\usepackage{fancyvrb}
\usepackage{tikz}
\usetikzlibrary{patterns, fit, positioning, calc, shapes.arrows}
\usepackage[active, tightpage, floats, displaymath]{preview}
\mathtoolsset{%
mathic=true
}
% Vectors and matrices
\renewcommand*{\vec}[1]{\mathbf{#1}}
\newcommand{\mat}[1]{\mathbf{#1}}
\newcommand{\trans}{\intercal}
% Operators
\DeclareMathOperator{\rank}{rank}
\DeclareMathOperator*{\argmin}{arg\,min}
\DeclareMathOperator*{\argmax}{arg\,max}
\begin{document}
\begin{figure}
\centering
% no longer needed
% \captionsetup[subfigure]{margin={2.5cm, 0cm}}
%empty subfugure to allow for overlap to the left
\begin{subfigure}[b]{0.15\textwidth}
\mbox{}
\end{subfigure}
\begin{subfigure}[b]{0.40\textwidth}
\centering
\begin{tikzpicture}[>=latex, shorten >=2pt, shorten <=2pt]
\node[draw, rectangle, label=below:the] (the) {\(\mat W\)};
\node[draw, rectangle, right=of the, label=below:cat] (cat) {\(\mat W\)};
\node[draw, rectangle, right=of cat, label=below:sat] (sat) {\(\mat W\)};
\node[draw, rectangle, fit=(the.west) (the.east), pattern=vertical lines, above=of the] (in_the) {};
\node[draw, rectangle, fit=(cat.west) (cat.east), pattern=vertical lines, above=of cat] (in_cat) {};
\node[draw, rectangle, fit=(sat.west) (sat.east), pattern=vertical lines, above=of sat] (in_sat) {};
\node[draw, rectangle, fit={($(cat.west) + (-8pt,0pt)$) ($(cat.east) + (8pt,0pt)$)}, pattern=vertical lines, above=2cm of cat] (in) {};
\node[draw, rectangle, above=of in, label=above:mat] (out) {\(\vec b\), \(\mat U\)};
% set the picture size to everything drawn so far
\useasboundingbox (current bounding box);
% not taken into account for the picture size
\node[left=of the, outer sep=0] (embed) {embed};
\node[above=2cm of embed, outer sep=0] (concatenate) {concatenate};
\node[above=1cm of concatenate, outer sep=0] {softmax};
% this belongs to the main part, but it doesn't increase its size
% otherwise it must be moved before \useasboundingbox
\foreach \word in {the, cat, sat}{%
\draw[->] (\word) -- (in_\word);
\draw[->] (in_\word) -- (in);
}
\draw[->] (in) -- (out);
\end{tikzpicture}
\caption{CBOW model}\label{fig:cbow}
\end{subfigure}
% no longer needed
% \captionsetup[subfigure]{margin={0cm,0cm}}
\begin{subfigure}[b]{0.35\textwidth}
\centering
\begin{tikzpicture}[>=latex, shorten >=2pt, shorten <=2pt]
\node[draw, rectangle, label=below:cat] (cat) {\(\mat W\)};
\node[draw, rectangle, fit=(cat.west) (cat.east), pattern=vertical lines, above=of cat] (in) {};
\node[draw, rectangle, above=2cmof in, label=above:on] (on) {\(\vec b\), \(\mat U\)};
\node[draw, rectangle, left=of on, label=above:sat] (sat) {\(\vec b\), \(\mat U\)};
\node[draw, rectangle, right=of on, label=above:the] (the) {\(\vec b\), \(\mat U\)};
\draw[->] (cat) -- (in);
\foreach \word in {sat, on, the}{%
\draw[->] (in) -- (\word);
}
\end{tikzpicture}
\caption{Skip\=/gram model}\label{fig:sg}
\end{subfigure}
\caption{\protect\Verb+Word2Vec+ with vocabulary size \(V\), context
size \(C\), and embedding size \(N\)}
\end{figure}
\end{document}
答案2
這是一個比我原來的(相對)簡單的答案(相對)不那麼簡單的方法,它更靈活一些,並且經過了更好的測試。它需要etoolbox
和xparse
。 (如果需要的話,您可以輕鬆地放棄後者,但這很方便。)
正如我所設定的,這會修改所有
tikzpicture
環境。如果需要的話,可以將其擴展為包含
\tikz
巨集。如果全域影響是不可取的,請刪除定義並僅在 的可選參數中
every picture
使用。mark out
tikzpicture
它允許調整左側、右側、兩側或兩者都不調整的材料。
基於 MWE 的簡單情況的唯一要求是在圖片中要標記用於放置標題\tikzmarkerwest
的圖片部分左側的位置處插入。\caption
如果您在圖片中完全不使用宏,則當圖片完成時,程式碼只會退回到圖片邊界框的左側。這發生在subfigure
範例中的第二個。
第一個代碼subfigure
被重新排列,以便所有\caption
應該忽略的內容都出現在圖片的第一部分之後。\tikzmarkerwest
然後插入以標記此時的左側。
...
\foreach \word in {the, cat, sat}{%
\draw[->] (\word) -- (in_\word);
\draw[->] (in_\word) -- (in);
}
\draw[->] (in) -- (out);
這就是我們想要\caption
用於放置的所有內容,因此現在標記圖片的左側。
\tikzmarkerwest
現在我們將這些內容放在該點的左側,該點\caption
應該被忽略。
\node[left=of the, outer sep=0] (embed) {embed};
\node[above=2cm of embed, outer sep=0] (concatenate) {concatenate};
\node[above=1cm of concatenate, outer sep=0] {softmax};
現在我們完成圖片並像往常一樣添加標題和標籤。
\end{tikzpicture}
\caption{CBOW model}\label{fig:cbow}
對於右側的材料,\tikzmarkereast
可以使用 代替 或 以及\tikzmarkerwest
。
在某些情況下,以這種方式重新排列圖片中的程式碼是不方便或不可能的。它只是不能輕易地按照所需的順序繪製(如果有的話)。為此,\tikzmarkereast
並\tikzmarkerwest
支援可選參數。如果指定,這應該是圓括號中的座標,就像通常的座標一樣。在這種情況下,放置標題時,指定座標右側或左側的所有內容都將被忽略。
支援此功能的程式碼定義巨集\tikzmarkerwest
如下。
\NewDocumentCommand \tikzmarkerwest { D () {current bounding box.west} } {%
\coordinate (tikz marker west) at (#1);
\let\tikzmarkerwestdefault\relax
}
這會(tikz marker west)
在適當的位置創建一個座標。然後它會確保\tikzmarkerwestdefault
沒有成功執行任何操作。
\tikzmarkereast
以同樣的方式定義。
\NewDocumentCommand \tikzmarkereast { D () {current bounding box.east} } {%
\coordinate (tikz marker east) at (#1);
\let\tikzmarkereastdefault\relax
}
我們確定\tikzmarkerwestdefault
並被\tikzmarkereast
定義。預設情況下,它們不執行任何操作。
\NewDocumentCommand \tikzmarkerwestdefault {} {}
\NewDocumentCommand \tikzmarkereastdefault {} {}
現在對於鈦kZ 代碼。
\tikzset{%
此樣式mark out
會新增要在目前圖片的開頭和結尾執行的程式碼(如果在環境的可選參數中給出)或所有圖片的開頭和結尾(如果配置如下)。
mark out/.style={%
execute at begin picture={%
\RenewDocumentCommand \tikzmarkerwestdefault {}
{%
\coordinate (tikz marker west) at (current bounding box.west);
}%
\RenewDocumentCommand \tikzmarkereastdefault {}
{%
\coordinate (tikz marker east) at (current bounding box.east);
}%
},
這重新定義了\tikzmarkerwestdefault
和巨集以在當前邊界框的左側和右側\tikzmarkereastdefault
建立座標(tikz marker west)
和。(tikz marker east)
這些只是定義,覆蓋預設的空定義。他們實際上還沒有創建任何座標。
execute at end picture={%
\tikzmarkerwestdefault
\tikzmarkereastdefault
在圖片的最後,我們執行\tikzmarkerwestdefault
.如果\tikzmarkerwest
已在圖片中調用,則不會成功執行任何操作。否則,它將在當前邊界框的左側建立標記,這是圖片的最終邊界框。同樣對於\tikzmarkereastdefault
.
\path let \p1=(tikz marker west), \p2=(current bounding box.west), \n1={\x1-\x2} in \pgfextra{\xdef\myadjustwest{\n1}} ;
這將計算當前邊界框左側x
座標部分(tikz marker west)
與座標部分之間的差異。x
通常,這將為 0pt。但是,如果\tikzmarkerwest
被調用,標記節點距當前邊界框左側的距離可能不為零。 (事實上,如果巨集已被調用,則可能是這種情況,因為這是使用巨集的唯一原因。)
(tikz marker east)
現在我們對目前邊界框的 和 右側執行相同的操作。
\path let \p1=(tikz marker east), \p2=(current bounding box.east), \n1={\x2-\x1} in \pgfextra{\xdef\myadjusteast{\n1}} ;
},
},
every picture/.style={mark out},
該行將該mark out
樣式套用至所有 TikZ 圖片。如果這會導致問題,請將其刪除並添加mark out
到您想要的圖片中。
}
\newlength\myadjustwest
\newlength\myadjusteast
確保\myadjustwest
和\myadjusteast
無論如何都可用。
\AfterEndEnvironment{tikzpicture}{%
\captionsetup{margin={\myadjustwest,\myadjusteast}}%
}{\typeout{OK!}}{\typeout{Oh, no!}}
這會適應所有環境的末端tikzpicture
以正確修改\caption
。如果您使用它,您應該用對自己有意義的消息來代替OK!
和Oh, no!
。
以下範例集說明了基本的可能性。如果你想相對於一個陰影矩形放置標題,你不能(很容易)遮蔽它的一部分,然後是另一個部分,然後是另一個部分,適當地標記階段之間的邊界框。因此,對於這種情況,我們使用\tikzmarkerwest
和/或 的可選參數\tikzmarkereast
來獲取聚焦於可見光譜的紅端、藍端和中間位左側的字幕的位置。
對於紅軍來說...
...
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.4] (r);
\tikzmarkereast(r)
...
對於布魯斯...
...
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.6] (b);
\tikzmarkerwest(b)
...
對於內臟...
...
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.1] (a) coordinate [pos=.5] (b);
\tikzmarkereast(b)
\tikzmarkerwest(a)
...
完整程式碼:
% arara: pdflatex
\pdfminorversion=7
% ateb: https://tex.stackexchange.com/a/377652/ addaswyd o gwestiwn d125q: https://tex.stackexchange.com/q/377476/
\documentclass[a4paper]{scrartcl}
\usepackage{mathtools,amssymb}
\usepackage[compatibility=false]{caption}
\usepackage[list]{subcaption}
\usepackage{fancyvrb,tikz,etoolbox,xparse}
\usetikzlibrary{patterns, fit, positioning, calc}
\usepackage[active, tightpage, floats, displaymath]{preview}
\mathtoolsset{%
mathic=true
}
\NewDocumentCommand \tikzmarkerwest { D () {current bounding box.west} } {%
\coordinate (tikz marker west) at (#1);
\let\tikzmarkerwestdefault\relax
}
\NewDocumentCommand \tikzmarkerwestdefault {} {}
\NewDocumentCommand \tikzmarkereast { D () {current bounding box.east} } {%
\coordinate (tikz marker east) at (#1);
\let\tikzmarkereastdefault\relax
}
\NewDocumentCommand \tikzmarkereastdefault {} {}
\tikzset{%
mark out/.style={%
execute at begin picture={%
\RenewDocumentCommand \tikzmarkerwestdefault {}
{%
\coordinate (tikz marker west) at (current bounding box.west);
}%
\RenewDocumentCommand \tikzmarkereastdefault {}
{%
\coordinate (tikz marker east) at (current bounding box.east);
}%
},
execute at end picture={%
\tikzmarkerwestdefault
\tikzmarkereastdefault
\path let \p1=(tikz marker west), \p2=(current bounding box.west), \n1={\x1-\x2} in \pgfextra{\xdef\myadjustwest{\n1}} ;
\path let \p1=(tikz marker east), \p2=(current bounding box.east), \n1={\x2-\x1} in \pgfextra{\xdef\myadjusteast{\n1}} ;
},
},
every picture/.style={mark out},
}
\newlength\myadjustwest
\newlength\myadjusteast
\AfterEndEnvironment{tikzpicture}{%
\captionsetup{margin={\myadjustwest,\myadjusteast}}%
}{\typeout{OK!}}{\typeout{Oh, no!}}
% for the examples
\definecolor{wave start}{wave}{380}
\definecolor{wave violet}{wave}{400}
\definecolor{wave indigo}{wave}{445}
\definecolor{wave blue}{wave}{475}
\definecolor{wave green}{wave}{510}
\definecolor{wave yellow}{wave}{570}
\definecolor{wave orange}{wave}{590}
\definecolor{wave red}{wave}{650}
\definecolor{wave end}{wave}{780}
\pgfdeclareverticalshading{wave}{100bp}{% manual 1088; xcolor manual; does not work to use wave model directly (?); https://science-edu.larc.nasa.gov/EDDOCS/Wavelengths_for_Colors.html
color(0bp)=(wave start);
color(25bp)=(wave start);
color(27bp)=(wave violet);% 400 nm
color(33bp)=(wave indigo);% 445nm
color(37bp)=(wave blue);% 475nm
color(41bp)=(wave green);% 510nm
color(49bp)=(wave yellow);% 570nm
color(51bp)=(wave orange);% 590nm
color(59bp)=(wave red);% 650nm
color(75bp)=(wave end);% 780nm
color(100bp)=(wave end)
}
\begin{document}
\begin{figure}
\centering
\begin{subfigure}[b]{0.60\textwidth}
\centering
\begin{tikzpicture}[>=latex, shorten >=2pt, shorten <=2pt]
\node[draw, label=below:the] (the) {\(\mathbf{W}\)};
\node[draw, right=of the, label=below:cat] (cat) {\(\mathbf{W}\)};
\node[draw, right=of cat, label=below:sat] (sat) {\(\mathbf{W}\)};
\node[draw, fit=(the.west) (the.east), pattern=vertical lines, above=of the] (in_the) {};
\node[draw, fit=(cat.west) (cat.east), pattern=vertical lines, above=of cat] (in_cat) {};
\node[draw, fit=(sat.west) (sat.east), pattern=vertical lines, above=of sat] (in_sat) {};
\node[draw, fit={($(cat.west) + (-8pt,0pt)$) ($(cat.east) + (8pt,0pt)$)}, pattern=vertical lines, above=2cm of cat] (in) {};
\node[draw, above=of in, label=above:mat] (out) {\(\mathbf{b}\), \(\mathbf{U}\)};
\foreach \word in {the, cat, sat}{%
\draw[->] (\word) -- (in_\word);
\draw[->] (in_\word) -- (in);
}
\draw[->] (in) -- (out);
\tikzmarkerwest
\node[left=of the, outer sep=0] (embed) {embed};
\node[above=2cm of embed, outer sep=0] (concatenate) {concatenate};
\node[above=1cm of concatenate, outer sep=0] {softmax};
\end{tikzpicture}
\caption{CBOW model}\label{fig:cbow}
\end{subfigure}
\begin{subfigure}[b]{0.35\textwidth}
\centering
\begin{tikzpicture}[>=latex, shorten >=2pt, shorten <=2pt]
\node[draw, label=below:cat] (cat) {\(\mathbf{W}\)};
\node[draw, fit=(cat.west) (cat.east), pattern=vertical lines, above=of cat] (in) {};
\node[draw, above=2cmof in, label=above:on] (on) {\(\mathbf{b}\), \(\mathbf{U}\)};
\node[draw, left=of on, label=above:sat] (sat) {\(\mathbf{b}\), \(\mathbf{U}\)};
\node[draw, right=of on, label=above:the] (the) {\(\mathbf{b}\), \(\mathbf{U}\)};
\draw[->] (cat) -- (in);
\foreach \word in {sat, on, the}{%
\draw[->] (in) -- (\word);
}
\end{tikzpicture}
\caption{Skip\=/gram model}\label{fig:sg}
\end{subfigure}
\caption{\protect\Verb+Word2Vec+ with vocabulary size \(V\), context size \(C\), and embedding size \(N\)}
\end{figure}
\begin{figure}
\centering
\begin{subfigure}{.33\linewidth}
\centering
\begin{tikzpicture}
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.4] (r);
\tikzmarkereast(r)
\end{tikzpicture}
\caption{Reds.}
\end{subfigure}\hfill
\begin{subfigure}{.33\linewidth}
\centering
\begin{tikzpicture}
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.6] (b);
\tikzmarkerwest(b)
\end{tikzpicture}
\caption{Blues.}
\end{subfigure}\hfill
\begin{subfigure}{.33\linewidth}
\centering
\begin{tikzpicture}
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.1] (a) coordinate [pos=.5] (b);
\tikzmarkereast(b)
\tikzmarkerwest(a)
\end{tikzpicture}
\caption{Innards.}
\end{subfigure}\par
\caption{Main figure}
\end{figure}
\end{document}
答案3
首先,我沒有編輯我的第一個答案,因為它可能對某些人有用。
這個新答案計算標題的邊距。為此,前言中有一些宏。然後必須放置三個命令。他們都是沒有任何爭論的。
在圖片中,必須先繪製主要部分(即標題應居中的部分)。然後\pgfremembermainx
必須插入。它設定座標來記住到目前為止最外面的 x 位置。之後,必須繪製與主要部分左側和右側重疊的部分。
必須將\end{tikzpicture}
指令放置在最後、之前的位置。\pgfgetoverlap
它計算兩側的重疊(相對於主要部分)並將其儲存在尺寸寄存器\overlapleft
和中\overlapright
。兩者都設置為全局,因此可以在tikzpicture
.注意:\pgfgetoverlap
計算重疊時不會考慮之後繪製的所有內容。
最後,在tikzpicture
和標題之間設定邊距\captionsetmargins
。它的影響是局部的,因為它在subfigure
環境中。它不應該在環境之外使用,因為它會設定所有標題的邊距,因為[subfigure]
這裡不能使用可選參數 ( )。當然,這只適用於圖片之後,因為重疊在圖片之前是未知的。
\documentclass[a4paper]{scrartcl}
\usepackage{mathtools}
\usepackage{amssymb}
\usepackage[compatibility=false]{caption}
\usepackage[list]{subcaption}
\usepackage{fancyvrb}
\usepackage{tikz}
\usetikzlibrary{patterns, fit, positioning, calc, shapes.arrows}
\usepackage[active, tightpage, floats, displaymath]{preview}
\mathtoolsset{%
mathic=true
}
% Vectors and matrices
\renewcommand*{\vec}[1]{\mathbf{#1}}
\newcommand{\mat}[1]{\mathbf{#1}}
\newcommand{\trans}{\intercal}
% Operators
\DeclareMathOperator{\rank}{rank}
\DeclareMathOperator*{\argmin}{arg\,min}
\DeclareMathOperator*{\argmax}{arg\,max}
%---------------------------------------------------------------------
% code for automatic setting of caption margins
\makeatletter
\newdimen\overlapleft
\newdimen\overlapright
\newcommand{\pgfremembermainx}{%
\coordinate (main west) at (current bounding box.west);
\coordinate (main east) at (current bounding box.east);
}
\newcommand{\pgfgetoverlap}{%
\pgfextractx{\@tempdima}{%
\pgfpointdiff{\pgfpointanchor{current bounding box}{west}}%
{\pgfpointanchor{main west}{center}}%
}%
\global\overlapleft=\@tempdima
\pgfextractx{\@tempdima}{%
\pgfpointdiff{\pgfpointanchor{main east}{center}}%
{\pgfpointanchor{current bounding box}{east}}%
}%
\global\overlapright=\@tempdima
}
\newcommand{\captionsetmargins}{%
% no additional calculation required here
\captionsetup{margin={\overlapleft,\overlapright}}%
}
\makeatother
%---------------------------------------------------------------------
\begin{document}
\begin{figure}
\centering
% not needed here
% \captionsetup[subfigure]{margin={2.5cm, 0cm}}
\begin{subfigure}[b]{0.60\textwidth}
\centering
\begin{tikzpicture}[>=latex, shorten >=2pt, shorten <=2pt]
\node[draw, rectangle, label=below:the] (the) {\(\mat W\)};
\node[draw, rectangle, right=of the, label=below:cat] (cat) {\(\mat W\)};
\node[draw, rectangle, right=of cat, label=below:sat] (sat) {\(\mat W\)};
\node[draw, rectangle, fit=(the.west) (the.east), pattern=vertical lines, above=of the] (in_the) {};
\node[draw, rectangle, fit=(cat.west) (cat.east), pattern=vertical lines, above=of cat] (in_cat) {};
\node[draw, rectangle, fit=(sat.west) (sat.east), pattern=vertical lines, above=of sat] (in_sat) {};
\node[draw, rectangle, fit={($(cat.west) + (-8pt,0pt)$) ($(cat.east) + (8pt,0pt)$)}, pattern=vertical lines, above=2cm of cat] (in) {};
\node[draw, rectangle, above=of in, label=above:mat] (out) {\(\vec b\), \(\mat U\)};
% remember the x-coordinates of the main part
\pgfremembermainx
% \useasboundingbox was here in the first answer
% not taken into account for the picture size
\node[left=of the, outer sep=0] (embed) {embed};
\node[above=2cm of embed, outer sep=0] (concatenate) {concatenate};
\node[above=1cm of concatenate, outer sep=0] {softmax};
% this belongs to the main part, but it doesn't increase its size
% otherwise it must be moved before \pgfremembermainx
\foreach \word in {the, cat, sat}{%
\draw[->] (\word) -- (in_\word);
\draw[->] (in_\word) -- (in);
}
\draw[->] (in) -- (out);
%for testing, if it also works with overlap to the right
%\node[draw, right= of sat] {t};
% must be right before \end{tikzpicture}, everything after it
% would not be taken into account for the calculation of the overlap
\pgfgetoverlap
\end{tikzpicture}
% setting the caption margins
% moving this here sets the margin locally (only for the current environment)
% and here the computed values for the margins are known
\captionsetmargins
\caption{CBOW model}\label{fig:cbow}
\end{subfigure}
% no longer needed
% \captionsetup[subfigure]{margin={0cm,0cm}}
\begin{subfigure}[b]{0.35\textwidth}
\centering
\begin{tikzpicture}[>=latex, shorten >=2pt, shorten <=2pt]
\node[draw, rectangle, label=below:cat] (cat) {\(\mat W\)};
\node[draw, rectangle, fit=(cat.west) (cat.east), pattern=vertical lines, above=of cat] (in) {};
\node[draw, rectangle, above=2cmof in, label=above:on] (on) {\(\vec b\), \(\mat U\)};
\node[draw, rectangle, left=of on, label=above:sat] (sat) {\(\vec b\), \(\mat U\)};
\node[draw, rectangle, right=of on, label=above:the] (the) {\(\vec b\), \(\mat U\)};
\draw[->] (cat) -- (in);
\foreach \word in {sat, on, the}{%
\draw[->] (in) -- (\word);
}
\end{tikzpicture}
\caption{Skip\=/gram model}\label{fig:sg}
\end{subfigure}
\caption{\protect\Verb+Word2Vec+ with vocabulary size \(V\), context
size \(C\), and embedding size \(N\)}
\end{figure}
\end{document}