2

I'm using the subfig package to handle subfigures and I'm getting a really puzzling error, where referencing with \ref{} to a subfigure assigns it the wrong figure number, even though the reference to the global figure does work:

A MWE example is the following:

\documentclass{report}

\usepackage{subfig}
\usepackage{caption}
\usepackage{lmodern} 
\usepackage{bm}

\begin{document}

\chapter{Title}

\captionsetup[figure]{position=top}
\begin{figure}[!htbp]
  \centering
  \begin{tabular}{cc}
  \subfloat[caption 1a]{
    \label{fig1a}
    \rule{3cm}{2cm}
  }
  &
  \subfloat[caption 1b]{
    \label{fig1b}
    \rule{3cm}{2cm}
  }
  \end{tabular}
  \caption{Sample caption.}
  \label{fig1}
\end{figure}


\begin{figure}[hbt]
  \centering
  \subfloat{
    \rule{3cm}{2cm}
    \label{fig2a}
  }
  \hspace{5mm}
  \subfloat{
    \rule{3cm}{2cm}
    \label{fig2b}
  }
  \caption{
  Referencing inside the caption.
  \texttt{\textbackslash subref\{fig2a\}}: \protect\subref{fig2a}, 
  \texttt{\textbackslash subref\{fig2b\}}: \protect\subref{fig2b}, 
  \texttt{\textbackslash subref*\{fig2a\}}: \protect\subref*{fig2a}, 
  \texttt{\textbackslash subref*\{fig2b\}}: \protect\subref*{fig2b},
  \texttt{\textbackslash ref\{fig2a\}}: \protect\ref{fig2a},
  \texttt{\textbackslash ref\{fig2b\}}: \protect\ref{fig2b},
  \texttt{\textbackslash ref\{fig2\}}: \protect\ref{fig2}.
  }
  \label{fig2}
\end{figure}

Subref works correctly: 
  \texttt{\textbackslash subref\{fig2a\}}:~\protect\subref{fig2a}, 
  \texttt{\textbackslash subref\{fig2b\}}:~\protect\subref{fig2b}, 
  \texttt{\textbackslash subref*\{fig2a\}}:~\protect\subref*{fig2a}, 
  \texttt{\textbackslash subref*\{fig2b\}}:~\protect\subref*{fig2b}.

$\quad$

Figure ref works correctly:
  \texttt{\textbackslash ref\{fig2\}}:~\protect\ref{fig2}.

$\quad$

Direct ref to subfigures doesn't:
  \texttt{\textbackslash ref\{fig2a\}}: \protect\ref{fig2a},
  \texttt{\textbackslash ref\{fig2b\}}: \protect\ref{fig2b},

\end{document}

What causes this, and how can I fix it?

  • 1
    You cannot say \captionsetup[figure]{position=top} and place the figure caption below the figure content. This way you are cheating subfig and subfig does not like it, As documented in section "The Caption Position Option" of the subfig documentation. – Axel Sommerfeldt Sep 11 '16 at 17:09
  • @Axel I will look at the docs in more detail in the morning, but in the meantime you could actually take a productive stance and suggest the correct way to produce the output as posed (caption at bottom, sublabels and subcaptions on top). In any case, from memory, this is almost certainly a documentation bug at the very least, either through unclear docs or through misleading answers on this site. – E.P. Sep 11 '16 at 23:09
  • 1
    Unfortunately I do not have a TeX system available at the moment, but \captionsetup[figure]{position=bottom} \captionsetup[subfigure]{position=top} should do the trick. – Axel Sommerfeldt Sep 12 '16 at 8:07
1

This turns out to be a very subtle error in terms of how the \captionsetups are handled. This behaviour goes away when the initial \captionsetup is removed, or when

\captionsetup[figure]{position=auto}

is placed between the two:

I hesitate to call this a bug because this is possibly not quite how subfig is meant to be used (though let's face it, when was the last time that a LaTeX package cared about how its users would respond to it and try to use it?), but it looks pretty buggy to me.

(And, if this looks obvious to anyone, consider that the two figures can be on different subfiles of a very long document (so good luck debugging that), that the second figure doesn't really need to invoke any \captionsetup because it doesn't need it, and that if the first figure tries to clean up after itself by setting position=auto, and the second file is not included when the top figure is first introduced (fairly reasonable), then subfig is prone to raise a warning that there are unused \captionsetups, actively fighting this fix.)

0

A major question is: Why are you mixing-and-mismatching the subfig and caption packages? Subtle and not-so-subtle incompatibilities are bound to arise.

If you want to keep using the caption package -- I can't see a reason for not wanting to do so, given that you're using the report document class -- you should almost certainly be dropping the subfig package and be using the subcaption package instead. For sure, the "very subtle error" you have encountered vanishes instantly.

A revised MWE:

\documentclass{report}

%%%\usepackage{subfig} % <-- use 'subcaption' instead
\usepackage{caption,subcaption}
\usepackage{lmodern} 
\usepackage[colorlinks]{hyperref}
\begin{document}

\setcounter{chapter}{1}

\begin{figure}[!htbp]
%%\captionsetup[figure]{position=top} % this is pointless, as explained in Axel's earlier comment

\centering
\begin{subfigure}{3cm}
\caption{caption 1a}\label{fig1a}
\rule{3cm}{2cm}
\end{subfigure}%
\hspace{2\tabcolsep}
\begin{subfigure}{3cm}
\caption{caption 1b}\label{fig1b}
\rule{3cm}{2cm}
\end{subfigure}

\caption{Sample caption.}\label{fig1}
\end{figure}

\begin{figure}[hbt]
  \centering
\begin{subfigure}{3cm}
\caption{caption 2a}\label{fig2a}
\rule{3cm}{2cm}
\end{subfigure}%
\hspace{2\tabcolsep}
\begin{subfigure}{3cm}
\caption{caption 2b}\label{fig2b}
\rule{3cm}{2cm}
\end{subfigure}

\caption[Referencing inside the caption.]{%
  Referencing inside the caption.
  \texttt{\textbackslash ref\{fig2a\}}: \ref{fig2a}, 
  \texttt{\textbackslash ref\{fig2b\}}: \ref{fig2b}, 
  \texttt{\textbackslash ref*\{fig2a\}}: \ref*{fig2a}, 
  \texttt{\textbackslash ref*\{fig2b\}}: \ref*{fig2b},
  \texttt{\textbackslash ref\{fig2a\}}: \ref{fig2a},
  \texttt{\textbackslash ref\{fig2b\}}: \ref{fig2b},
  \texttt{\textbackslash ref\{fig2\}}:  \ref{fig2}.
  }
  \label{fig2}
\end{figure}

ref works correctly: 
  \verb+\ref{fig2a}+: \ref{fig2a}, 
  \verb+\ref{fig2b}+: \ref{fig2b}, 
  \verb+\ref*{fig2a}+: \ref*{fig2a}, 
  \verb+\ref*{fig2b}+: \ref*{fig2b}.


Figure ref works correctly:
  \verb+\ref{fig2}+: \ref{fig2}.


Direct refs to subfigures also work:
  \verb+\ref{fig2a}+: \ref{fig2a},
  \verb+\ref{fig2b}+: \ref{fig2b},

\end{document}
  • This comes waaaay too late for me to reproduce that workflow (and I do not appreciate the 'you should ask yourself...', particularly for something that comes in this late). Ultimately I went back to subfigure, and the document is published and not changeable. Either way, I do not consider something that requires changing a 200+ page document from a \subfigure{} syntax to a \begin{subfigure} structure to be particularly close to a solution. I can no longer recall the full details of the comparison, but subcaption was also not a complete solution to my requirements at the time. – E.P. Feb 15 '17 at 9:56
  • Ah, yes. If I recall correctly, subcaption offers no facility to fully tune the way figure parts are referenced, as per the requirements in this question. As I recall, the only such solution I found was this one, and redefining \thesubfigure completely breaks the third requirement. This is all from memory, though. – E.P. Feb 15 '17 at 10:09
  • @E.P. - I can well appreciate that this answer comes too late to meet your formatting needs. I didn't come across your posting when you made it in Sept 2016. However, it was pushed to the top page by the "community bot" earlier today, and that's the first time I saw it. As you may well appreciate, I had no knowledge until now of the specifics of your 'real' document, e.g., that it's more than 200 pages long. My answer, then, was intended mainly for the benefit of future readers of your posting. – Mico Feb 15 '17 at 10:48
  • @E.P. - Incidentally, I must disagree with your claim that subcaption doesn't offer sufficient customizability of cross-references to subfigures. (Some of the answers you located are quite old and don't advantage of the most recent version of the subcaption package.) However, as you've stated that your document is published and unchangeable, I won't bother providing an answer. – Mico Feb 15 '17 at 10:53
  • Frankly, the takeaway was that everything later than subfigure is unusable for my needs, but if you can show that subcaption does actually offer sufficient customizability then that is indeed valuable. An answer to the previous question I linked to showing that subcaption can actually do all of that would fit the bill. If it can't actually do it, then maybe it's time to reconsider its position as the end-all-be-all of subreference handling. – E.P. Feb 15 '17 at 11:02

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.