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}

sudosensei
  • 4,072

1 Answers1

4

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}
Torbjørn T.
  • 206,688
  • 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