4

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.}

Output

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,
  ]

    \addplot+[samples=10] {rnd};

  \end{axis}

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

    \addplot+[samples=10] {rnd};
  \end{axis}

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

  % Martin's answer: https://tex.stackexchange.com/a/14340/32206
  \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.

\usepackage[colorlinks]{hyperref}

\begin{document}
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}.

\begin{figure}
  \centering
  \renewcommand{\figFilename}{figure}
  \tikzsetnextfilename{\figFilename}
  \input{\figFilename.tikz}
  \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.}
  \label{fig:\figFilename}
\end{figure}

\end{document}
3

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,
  ]

    \addplot+[samples=10] {rnd};

  \end{axis}

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

    \addplot+[samples=10] {rnd};
  \end{axis}

  \begin{axis}[%
    name={fig3},
    at={($(fig2.south) + (0,-1.5cm)$)},
    anchor=north,
    scale only axis,
    width=5cm,
    height=2cm,
  ]
    \addplot+[samples=10] {rnd};
  \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.

\usepackage[colorlinks]{hyperref}

\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}

enter image description here

Addendum

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,
  ]

    \addplot+[samples=10] {rnd};

  \end{axis}

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

    \addplot+[samples=10] {rnd};
  \end{axis}

  \begin{axis}[%
    name={fig3},
    at={($(fig2.south) + (0,-1.5cm)$)},
    anchor=north,
    scale only axis,
    width=5cm,
    height=2cm,
  ]
    \addplot+[samples=10] {rnd};
  \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.

\usepackage[colorlinks]{hyperref}

\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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.