Considere el siguiente 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:
Que se compone en:
Como puede ver, he "centrado" el título "(a) modelo CBOW" usando \captionsetup[subfigure]{margin={2.5cm, 0cm}}
. Mi pregunta es: ¿es posible no tener que hacer esto? ¿O al menos calcular de alguna manera el ancho correcto por el cual necesito compensar el título?
Respuesta1
Puedes usarlo \useasboundingbox
en TikZ para establecer la dimensión de la imagen. Luego, TikZ ignorará todo lo que haya después de ese comando para calcular el tamaño de la imagen. Con (current bounding box)
puedes consultar el tamaño de la imagen hasta el momento. Mientras dibujes todo lo que debería contar para el tamaño del papel, antes de la línea \useasboundingbox (current bounding box)
la imagen tendrá el tamaño deseado.
Además, se necesita un vacío subfigure
para permitir la superposición hacia la izquierda. Entonces tiene que ser el primero. Por supuesto, es necesario ajustar el ancho de la subfigura izquierda (bueno, ahora la del medio).
\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}
Respuesta2
Este es un método (relativamente) menos simple que mi respuesta original (relativamente) simple, que es un poco más flexible y ligeramente mejor probada. Requiere etoolbox
y xparse
. (Si lo desea, puede prescindir fácilmente de este último, pero es conveniente).
Tal como configuré las cosas, esto modifica todos
tikzpicture
los entornos.Podría ampliarse para incluir
\tikz
macros, si fuera necesario.Si el impacto global no es deseable, elimine la
every picture
definición y simplemente utilícelamark out
en el argumento opcional totikzpicture
.
Permite el ajuste del material a la izquierda, a la derecha, a ambos o a ninguno.
El único requisito para el caso simple basado en el MWE es insertar \tikzmarkerwest
en el punto de la imagen donde se desea marcar la parte izquierda de la imagen que \caption
se debe utilizar para colocar el título. Si no utiliza la macro en absoluto en la imagen, el código simplemente vuelve a caer a la izquierda del cuadro delimitador de la imagen, cuando la imagen está completa. Esto sucede en el segundo subfigure
del ejemplo.
El código del primero subfigure
se reordena, de modo que todo lo que \caption
se debe ignorar viene después de la primera parte de la imagen. \tikzmarkerwest
Luego se inserta para marcar el lado izquierdo en este punto.
...
\foreach \word in {the, cat, sat}{%
\draw[->] (\word) -- (in_\word);
\draw[->] (in_\word) -- (in);
}
\draw[->] (in) -- (out);
Eso es todo lo que queremos \caption
usar para la ubicación, así que marque ahora la izquierda de la imagen.
\tikzmarkerwest
Ahora ponemos las cosas a la izquierda de ese punto, que \caption
deberíamos ignorar.
\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};
Ahora terminamos la imagen y agregamos el título y la etiqueta como de costumbre.
\end{tikzpicture}
\caption{CBOW model}\label{fig:cbow}
Para el material de la derecha, \tikzmarkereast
se puede utilizar en lugar de o además de \tikzmarkerwest
.
En algunos casos, resulta inconveniente o imposible reorganizar el código de una imagen de esta manera. Simplemente no se puede dibujar fácilmente, en todo caso, en el orden requerido. Por este motivo, \tikzmarkereast
apoye \tikzmarkerwest
un argumento opcional. Si se especifica, debería ser una coordenada entre paréntesis, como es habitual para las coordenadas. En este caso, todo lo que esté a la derecha o izquierda de la coordenada especificada se ignorará al colocar el título.
El código que admite esto define la macro \tikzmarkerwest
de la siguiente manera.
\NewDocumentCommand \tikzmarkerwest { D () {current bounding box.west} } {%
\coordinate (tikz marker west) at (#1);
\let\tikzmarkerwestdefault\relax
}
Esto crea una coordenada (tikz marker west)
en el lugar apropiado. Luego se asegura de que \tikzmarkerwestdefault
no haga nada correctamente.
\tikzmarkereast
se define de la misma manera.
\NewDocumentCommand \tikzmarkereast { D () {current bounding box.east} } {%
\coordinate (tikz marker east) at (#1);
\let\tikzmarkereastdefault\relax
}
Nos aseguramos \tikzmarkerwestdefault
y \tikzmarkereast
estamos definidos. Por defecto, no hacen nada.
\NewDocumentCommand \tikzmarkerwestdefault {} {}
\NewDocumentCommand \tikzmarkereastdefault {} {}
Ahora para el TikCódigo Z.
\tikzset{%
El estilo mark out
agrega código que se ejecutará al principio y al final de la imagen actual, si se proporciona en el argumento opcional del entorno, o de todas las imágenes, si se configura como se muestra a continuación.
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);
}%
},
Esto redefine nuestras macros \tikzmarkerwestdefault
y \tikzmarkereastdefault
para crear coordenadas (tikz marker west)
y (tikz marker east)
a la izquierda y a la derecha del cuadro delimitador actual. Estas son sólo definiciones, que anulan las vacías predeterminadas. En realidad, todavía no crean ninguna coordenada.
execute at end picture={%
\tikzmarkerwestdefault
\tikzmarkereastdefault
Al final de la imagen ejecutamos \tikzmarkerwestdefault
. Si \tikzmarkerwest
se ha llamado dentro de la imagen, esto no hará nada con éxito. De lo contrario, creará el marcador a la izquierda del cuadro delimitador actual, que es el cuadro delimitador final de la imagen. De manera similar para \tikzmarkereastdefault
.
\path let \p1=(tikz marker west), \p2=(current bounding box.west), \n1={\x1-\x2} in \pgfextra{\xdef\myadjustwest{\n1}} ;
Esto calcula la diferencia entre la x
parte de la (tikz marker west)
coordenada y la x
parte de la coordenada a la izquierda del cuadro delimitador actual. Normalmente, será 0 puntos. Pero, si \tikzmarkerwest
se ha llamado, la distancia del nodo marcador desde la izquierda del cuadro delimitador actual puede ser distinta de cero. (De hecho, si se ha llamado a la macro, presumiblemente este será el caso, ya que esa es la única razón para usar la macro).
Ahora hacemos lo mismo para (tikz marker east)
y a la derecha del cuadro delimitador actual.
\path let \p1=(tikz marker east), \p2=(current bounding box.east), \n1={\x2-\x1} in \pgfextra{\xdef\myadjusteast{\n1}} ;
},
},
every picture/.style={mark out},
Esta línea aplica el mark out
estilo a todos los Ti.kImágenes Z. Si esto causa problemas, elimínelo y agréguelo mark out
a las imágenes para las que lo desea.
}
\newlength\myadjustwest
\newlength\myadjusteast
Asegúrese \myadjustwest
y \myadjusteast
esté disponible independientemente.
\AfterEndEnvironment{tikzpicture}{%
\captionsetup{margin={\myadjustwest,\myadjusteast}}%
}{\typeout{OK!}}{\typeout{Oh, no!}}
Esto adapta el final de todos tikzpicture
los entornos para modificarlos \caption
correctamente. Debes sustituir mensajes significativos en lugar de OK!
y Oh, no!
, si usas esto.
El siguiente conjunto de ejemplos ilustra las posibilidades básicas. Si desea colocar el título en relación con, digamos, un rectángulo sombreado, no puede (nada fácilmente) sombrear una parte del mismo, luego otra parte y luego otra parte, marcando apropiadamente el cuadro delimitador entre las etapas. Por lo tanto, para este caso, utilizamos los argumentos opcionales for \tikzmarkerwest
y/o \tikzmarkereast
para obtener posiciones para los subtítulos que se centran en el extremo rojo del espectro de luz visible, el extremo azul y un bit intermedio a la izquierda del centro.
Para los rojos...
...
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.4] (r);
\tikzmarkereast(r)
...
Para los azules...
...
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.6] (b);
\tikzmarkerwest(b)
...
Para las entrañas...
...
\shade [shading=wave, shading angle=90] (0,0) rectangle ++(\linewidth,1) coordinate [pos=.1] (a) coordinate [pos=.5] (b);
\tikzmarkereast(b)
\tikzmarkerwest(a)
...
Código completo:
% 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}
Respuesta3
Primero, no edité mi primera respuesta, porque tal como está podría ser útil para algunas personas.
Esta nueva respuesta calcula los márgenes del título. Para ello hay algunas macros en el preámbulo. Y luego hay que colocar tres comandos. Todos ellos están sin ningún argumento.
En la imagen, primero se debe dibujar la parte principal (es decir, la parte bajo la cual se debe centrar el título). Luego \pgfremembermainx
hay que insertarlo. Estableció coordenadas para recordar las posiciones x más externas hasta el momento. Después de eso, se deben dibujar las partes que se superponen a la parte principal a la izquierda y a la derecha.
Justo al final, justo antes , se debe colocar \end{tikzpicture}
el comando . \pgfgetoverlap
Calcula la superposición (en relación con la parte principal) en ambos lados y los almacena en los registros de dimensiones \overlapleft
y \overlapright
. Ambos están configurados de forma global, por lo que se pueden utilizar después del archivo tikzpicture
. Nota: todo lo que se dibuje después \pgfgetoverlap
no se tendrá en cuenta para calcular la superposición.
Y finalmente entre el tikzpicture
y el título se establecen los márgenes con \captionsetmargins
. Su efecto es local ya que está en el subfigure
medio ambiente. No debe usarse fuera del entorno, porque establecería los márgenes para todos los títulos ya que el argumento opcional ( [subfigure]
) no se puede usar aquí. Por supuesto, esto sólo funciona después de la imagen, porque antes de ella no se conocen las superposiciones.
\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}