# How to refer to parts of a single externalised graphic, such as multiple pgfplots (similar to subfloat/subcaption)?

I am looking for a way to refer, from within normal text or captions, to parts of TikZ graphics which I have labeled myself with (a), (b) etc. With subcaption and multiple separate figures I'd use something like \subref{label} from a caption and \ref{label} in normal text. But I have not found a similar approach for when I manually place labels to figures.

I already found a way of achieving this but it does not work with externalised graphics. Plus, I believe that this approach is too cumbersome and I am hoping for an alternative.

I am basically using Martin's answer here, which works by using a \hypertarget on the custom label in the TikZ environment and then linking to it from somewhere else using \hyperlink.

For example, I can refer to the whole figure and three of its labeled parts like so from the main text:

Overall figure in Fig.~\ref{fig:figure}. Also see Fig.~\hyperlink{subfig:a}{1a}, Fig.~\hyperlink{subfig:b}{1b} and Fig.~\hyperlink{subfig:c}{1c}.


Or like so from a caption (not sure why \protect is needed):

\caption{\protect\hyperlink{subfig:a}{\subcaptiontext{a}} shows this; \protect\hyperlink{subfig:b}{\subcaptiontext{b}} shows that; and \protect\hyperlink{subfig:c}{\subcaptiontext{c}} this and that.}


But this is not convenient because I have to type the figure number and label manually to link to the interesting parts which defeats the whole purpose. Plus, this works for non-externalised graphics, but the hyperlinks point to nowhere with externalisation enabled.

I also tried using subcaption's \phantomcaption, but I couldn't get it to work. Maybe there's a simple solution using subcaption.

I'd be happy to see solutions that either fix my current approach or suggest an alternative, less cumbersome method. I prefer the latter.

# MWE:

\documentclass{article}

\newcommand{\figFilename}{} % Store the figure filename for convenience.
\newcommand{\subcaptiontext}[1]{\textsf{\textbf{(#1)}}} % Custom label format.

\usepackage{filecontents}
\begin{filecontents*}{figure.tikz}
\begin{tikzpicture}
\begin{axis}[%
name={fig1},
scale only axis,
width=5cm,
height=2cm,
]

\end{axis}

\begin{axis}[%
name={fig2},
at={($(fig1.south) + (0,-1.5cm)$)},
anchor=north,
scale only axis,
width=5cm,
height=2cm,
]

\end{axis}

\begin{axis}[%
name={fig3},
at={($(fig2.south) + (0,-1.5cm)$)},
anchor=north,
scale only axis,
width=5cm,
height=2cm,
]
\end{axis}

\node (label1) at ($(fig1.north west)$) [above=0.3cm] {\hypertarget{subfig:a}{\subcaptiontext{a}}};
\node (label2) at ($(fig2.north west)$) [above=0.3cm] {\hypertarget{subfig:b}{\subcaptiontext{b}}};
\node (label3) at ($(fig3.north west)$) [above=0.3cm] {\hypertarget{subfig:c}{\subcaptiontext{c}}};
\end{tikzpicture}%
\end{filecontents*}

\usepackage{caption}
\usepackage{subcaption}

\usepackage{pgfplots}
\usetikzlibrary{calc,external}
\pgfplotsset{compat=1.10}
% \tikzexternalize % Comment out to get working hyperlinks.

\begin{document}

\begin{figure}
\centering
\renewcommand{\figFilename}{figure}
\tikzsetnextfilename{\figFilename}
\input{\figFilename.tikz}
\label{fig:\figFilename}
\end{figure}

\end{document}


The hyperlinks wont lead directly to the subfigures, but other than that it works. Note that \phantomsubcaptions must be placed within a group ({}).

\documentclass{article}

\newcommand{\figFilename}{} % Store the figure filename for convenience.
\newcommand{\subcaptiontext}[1]{\textsf{\textbf{(#1)}}} % Custom label format.

\usepackage{filecontents}
\begin{filecontents*}{figure.tikz}
\begin{tikzpicture}
\begin{axis}[%
name={fig1},
scale only axis,
width=5cm,
height=2cm,
]

\end{axis}

\begin{axis}[%
name={fig2},
at={($(fig1.south) + (0,-1.5cm)$)},
anchor=north,
scale only axis,
width=5cm,
height=2cm,
]

\end{axis}

\begin{axis}[%
name={fig3},
at={($(fig2.south) + (0,-1.5cm)$)},
anchor=north,
scale only axis,
width=5cm,
height=2cm,
]
\end{axis}

\node (label1) at ($(fig1.north west)$) [above=0.3cm] {\subcaptiontext{a}};
\node (label2) at ($(fig2.north west)$) [above=0.3cm] {\subcaptiontext{b}};
\node (label3) at ($(fig3.north west)$) [above=0.3cm] {\subcaptiontext{c}};

\end{tikzpicture}%
\end{filecontents*}

\usepackage{caption}
\usepackage{subcaption}

\usepackage{pgfplots}
\usetikzlibrary{calc,external}
\pgfplotsset{compat=1.10}
\tikzexternalize % Comment out to get working hyperlinks.

\begin{document}
Overall figure in Fig.~\ref{fig:figure}. Also see Fig.~\ref{a}, Fig.~\ref{b} and Fig.~\ref{c}.

\begin{figure}
\centering
\renewcommand{\figFilename}{figure}
\tikzsetnextfilename{\figFilename}
\input{\figFilename.tikz}
{%
\phantomsubcaption\label{a}
\phantomsubcaption\label{b}
\phantomsubcaption\label{c}%
}
\caption{\subref{a} shows this; \subref{b} shows that; and \subref{c} this and that.}
\label{fig:\figFilename}
\end{figure}

\end{document}


If you define a text width for the nodes containing the sublabels, it seems that using \subcaption{} directly in node also works just fine. That gives you automatic incrementing of the sub caption number, and consistent formatting with other subcaptions.

\documentclass{article}

\newcommand{\figFilename}{} % Store the figure filename for convenience.
\usepackage{filecontents}
\begin{filecontents*}{figure.tikz}
\begin{tikzpicture}
\begin{axis}[%
name={fig1},
scale only axis,
width=5cm,
height=2cm,
]

\end{axis}

\begin{axis}[%
name={fig2},
at={($(fig1.south) + (0,-1.5cm)$)},
anchor=north,
scale only axis,
width=5cm,
height=2cm,
]

\end{axis}

\begin{axis}[%
name={fig3},
at={($(fig2.south) + (0,-1.5cm)$)},
anchor=north,
scale only axis,
width=5cm,
height=2cm,
]
\end{axis}

\node (label1) at ($(fig1.north west)$) [above=0.3cm,text width=2em,align=center] {\subcaption{}};
\node (label2) at ($(fig2.north west)$) [above=0.3cm,text width=2em,align=center] {\subcaption{}};
\node (label3) at ($(fig3.north west)$) [above=0.3cm,text width=2em,align=center] {\subcaption{}};

\end{tikzpicture}%
\end{filecontents*}

\usepackage{caption}
\usepackage{subcaption}

\usepackage{pgfplots}
\usetikzlibrary{calc,external}
\pgfplotsset{compat=1.10}
\tikzexternalize % Comment out to get working hyperlinks.

\begin{document}
Overall figure in Fig.~\ref{fig:figure}. Also see Fig.~\ref{a}, Fig.~\ref{b} and Fig.~\ref{c}.

\begin{figure}
\centering
\renewcommand{\figFilename}{figure}
\tikzsetnextfilename{\figFilename}
\input{\figFilename.tikz}
{%
\phantomsubcaption\label{a}
\phantomsubcaption\label{b}
\phantomsubcaption\label{c}%
}
\caption{\subref{a} shows this; \subref{b} shows that; and \subref{c} this and that.}
\label{fig:\figFilename}
\end{figure}

\end{document}

• Nice one! Thanks. In theory, what would be required to make the hyperlinks point to the actual subfigures? Would it help if \phantomcaption was used in the nodes for example? – sudosensei May 16 '14 at 20:39
• @sudosensei I guess so. I didn't test, because I assumed you'll get the same problem when externalising the figure as with your own code. – Torbjørn T. May 16 '14 at 20:49
• \phantomsubcaptions do work inside the TikZ environment if they are wrapped in \tikzexternaldisable\phantomsubcaption\tikzexternalenable. But the links point to the same place so your solution is much more convenient! Thank you once again! – sudosensei May 17 '14 at 12:12
• Is there a way to keep the custom defined \subcaptiontext in sync with the settings of the subcaption package, e.g. the settings made by \captionsetup? – Cornelius Sicker Feb 14 '17 at 16:49
• @CorneliusSicker I edited, looks like it's possible to use \subcaption as well, which should accomplish just that. – Torbjørn T. Feb 14 '17 at 18:17