Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to reference a subfigure in my text but it is numbered incorrectly. Here is a minimal working example:

enter image description here

\documentclass{scrartcl}

\usepackage[demo]{graphicx}
\usepackage{subfig}

\begin{document}
    \begin{figure}
        \caption{Two pictures side by side}
        \label{img:both}
        \subfloat[first picture]{
            \includegraphics[width=5cm]{name}
            \label{img:first}
        }
        \subfloat[second picture]{
            \includegraphics[width=5cm]{name}
            \label{img:second}
        }
    \end{figure}

    This example shows that figure \ref{img:second} has a wrong reference number.
    But the complete float is referenced correctly: \ref{img:both}
\end{document}
share|improve this question
1  
Welcome ot TeX.sx! Nice post with a complete MWE! –  Peter Jansson Feb 14 '13 at 21:03
1  
Welcome to TeX.sx! I'd say that it's a very good first post! –  egreg Feb 14 '13 at 21:03
    
Thanks, i did my best. –  Loofmann Feb 16 '13 at 12:12

5 Answers 5

up vote 5 down vote accepted

The subfig package is strongly dependent on the knowledge of the caption position -- is it above or below the figure or table?

An except of the subfig package documentation:

3.1.5 The Caption Position Option

The caption package ‘position’ option specifies whether the caption appears before or after the figure or table. This can adjust the relative spacing used to separate the float from the surrounding text. However, for the subfig package, it serves a more important function. That is it determines if the sub-floats belong to or are associated with the last \caption command to be given, or the next one to be executed sometime in the future. If you find that you sub-references do not agree with the top-level labels, than you may need to specifically set the ‘position’. This is best done when loading the caption package, but may be done at anytime with the \captionsetup command.

So usually this can be fixed using the correct position settings:

\documentclass{article}

\usepackage[demo]{graphicx}
\usepackage{subfig}

% Telling the subfig package the desired caption positions
\captionsetup[figure]{position=t}
\captionsetup[subfigure]{position=b}

\begin{document}
    \begin{figure}
        \caption{Two pictures side by side}
        \label{img:both}
        \subfloat[first picture]{
            \includegraphics[width=5cm]{name}
            \label{img:first}
        }
        \subfloat[second picture]{
            \includegraphics[width=5cm]{name}
            \label{img:second}
        }
    \end{figure}

    This example shows that figure \ref{img:second} has a wrong reference number.
    But the complete float is referenced correctly: \ref{img:both}
\end{document}

However, KOMA-Script is some kind of special here because it has its own options and commands for specifying the main caption position. The caption/subfig package respects (and supports) the KOMA-Script approach, making the code line \captionsetup[figure]{position=t} not only superfluous but without any effect. (See caption package documentation for details, section about "KOMA-Script".)

So with KOMA-Script classes, one need to use the options and/or commands offered by KOMA-Script instead, at least for the main caption. However, although there is an option called "captions=figureheading" this option has no effect, KOMA-Script is still using \captionbelow instead of \captionabove internally for typesetting the main caption:

\documentclass[captions=figureheading]{scrartcl}

% Dirty hack to see if \captionabove or \captionbelow is used internally
\let\captionaboveORI\captionabove
\def\captionabove{\typeout{!captionabove!}\captionaboveORI}
\let\captionbelowORI\captionbelow
\def\captionbelow{\typeout{!captionbelow!}\captionbelowORI}

\usepackage[demo]{graphicx}
\usepackage{subfig}

% Telling the subfig package the desired caption position
\captionsetup[subfigure]{position=b}

\begin{document}
    \begin{figure}
        \caption{Two pictures side by side} % will use \captionbelow instead of \captionabove
        \label{img:both}
        \subfloat[first picture]{
            \includegraphics[width=5cm]{name}
            \label{img:first}
        }
        \subfloat[second picture]{
            \includegraphics[width=5cm]{name}
            \label{img:second}
        }
    \end{figure}

    This example shows that figure \ref{img:second} has a wrong reference number.
    But the complete float is referenced correctly: \ref{img:both}
\end{document}

This seems to be a bug in KOMA-Script, and the fact that the option captions=figureheading exists for about two years and nobody has noticed this problem before shows that this setting for figure captions is very uncommon.

Luckily there is a simple workaround for that problem: Using \captionabove explicitly instead of using \caption (which will use either \captionabove or \captionbelow implicitly):

\documentclass[captions=figureheading]{scrartcl}

\usepackage[demo]{graphicx}
\usepackage{subfig}

% Telling the subfig package the desired caption position
\captionsetup[subfigure]{position=b}

\begin{document}
    \begin{figure}
% Since "captions=figureheading" is not working as desired we use \captionabove here
        \captionabove{Two pictures side by side}
        \label{img:both}
        \subfloat[first picture]{
            \includegraphics[width=5cm]{name}
            \label{img:first}
        }
        \subfloat[second picture]{
            \includegraphics[width=5cm]{name}
            \label{img:second}
        }
    \end{figure}

    This example shows that figure \ref{img:second} has a wrong reference number.
    But the complete float is referenced correctly: \ref{img:both}
\end{document}

And voilà the reference will be correct, even with KOMA-Script.

share|improve this answer
    
Thanks Axel, this is not only a MWE but the minimal working solution. I prefer it as it is easy to remember and kind of self-explanatory. To be clear, it works just with the \captionabove command. –  Loofmann Feb 16 '13 at 12:32

subfig checks whether the caption is placed at the top of a figure or at the bottom. This is to allow for writing the appropriate "parent" counter with the subfloat counter, which might only be updated with the parent \caption. A global replacement strategy to avoid this comes with a patch from etoolbox:

\usepackage{subfig,etoolbox}% http://ctan.org/pkg/{subfig,etoolbox}
\makeatletter
\AtBeginDocument{\patchcmd{\sf@subfloat}% <cmd>
  {\maincaptiontopfalse}% <search>
  {\maincaptiontoptrue}% <replace>
  {}{}}% <success><failure>
\makeatother

The above (globally changing \maincaptiontopfalse to \maincaptiontoptrue) stems from the conditional "parent" counter increment contained within a subsidiary macro after calling \subfloat called \sf@subfloat (comments added):

\def\sf@subfloat{%
  \begingroup
    \@ifundefined{caption@setfloattype}%
      \caption@settype
      \caption@setfloattype
          \@captype
    \sf@ifpositiontop{% <------------ Check caption position
      \maincaptiontoptrue
    }{%
      \maincaptiontopfalse
    }%
    \caption@settype{subfloat}%
    \caption@settype{sub\@captype}%
    \let\sf@oldlabel=\label
    \let\label=\subfloat@label
    \ifmaincaptiontop\else
      \advance\@nameuse{c@\@captype}\@ne% <--- Step "parent" counter when \maincaptiontopfalse
    \fi
    \refstepcounter{sub\@captype}%
    \setcounter{sub\@captype @save}{\value{sub\@captype}}%
    \@ifnextchar [%  %] match left bracket
      {\sf@@subfloat}%
      {\sf@@subfloat[\@empty]}}

Here's a full MWE:

enter image description here

\documentclass{scrartcl}% http://ctan.org/pkg/koma-script

\usepackage[demo]{graphicx}% http://ctan.org/pkg/graphicx
\usepackage{subfig,etoolbox}% http://ctan.org/pkg/{subfig,etoolbox}
\makeatletter
\AtBeginDocument{\patchcmd{\sf@subfloat}% <cmd>
  {\maincaptiontopfalse}% <search>
  {\maincaptiontoptrue}% <replace>
  {}{}}% <success><failure>
\makeatother

\begin{document}
\begin{figure}
  \centering
  \caption{Two pictures side by side}
  \label{img:both}
  \subfloat[first picture]{
    \includegraphics[width=5cm]{name}
    \label{img:first}
  } \qquad
  \subfloat[second picture]{
    \includegraphics[width=5cm]{name}
    \label{img:second}
  }
\end{figure}

This example shows that figure \ref{img:second} has a wrong reference number.
But the complete float is referenced correctly: \ref{img:both}.
\end{document}
share|improve this answer
    
It works, but I prefer the solution of Axel below because it does not require an additional package. Thanks Werner. –  Loofmann Feb 16 '13 at 12:38

There's a weird behavior of subfig that seems to work correctly only if the main caption is under the subfloats.

I can offer a rather horrible fix if you really want to have your main caption above the subfloats:

\documentclass{scrartcl}

\usepackage[demo]{graphicx}
\usepackage{subfig}

\begin{document}
\begin{figure}
\centering
\caption{Two pictures side by side}
\label{img:both}
\addtocounter{figure}{-1}

\subfloat[first picture\label{img:first}]
  {%
   \includegraphics[width=5cm]{name}%
  }
\qquad
\subfloat[second picture\label{img:second}]
  {\includegraphics[width=5cm]{name}}

\stepcounter{figure}
\end{figure}

This example shows that figure \ref{img:second} has the correct reference number.
But the complete float is referenced correctly: \ref{img:both}
\end{document}

The label to the subfloats are best placed inside the argument to \subfloat.

Be careful with the spurious spaces in the mandatory argument to \subfloat; I've used two possible ways of inputting it that cure them. (Indentation is optional, I prefer not to indent the contents of "first level" environments.)

enter image description here

share|improve this answer
    
No, this is not a weird behavior of subfig, it's a well documented behavior instead. –  Axel Sommerfeldt Feb 15 '13 at 10:53
    
@AxelSommerfeldt I beg to differ; if it's documented, it's hard to find where and the manual references position=top, so one expects this works. –  egreg Feb 15 '13 at 11:11
    
Yes, I agree it's hard to find. But IMHO that's a generic problem with package documentations: If they are documenting not enough, the documentation is short, but important facts are missing. If they are documenting too much, it may be hard to find the desired information, especially since LaTeX package authors are some kind of "code hackers" and not professional documenters. (And writing well-arranged but complete documentation is far from being an easy task.) –  Axel Sommerfeldt Feb 15 '13 at 11:34
    
(What is missing here is a hint about the KOMA-Script stuff within the subfig documentation of the position= option. BUT: It has clear hints about reading the caption package documentation additionally, and the documentation about position= there has a clear hint (with an info mark) about KOMA-Script.) –  Axel Sommerfeldt Feb 15 '13 at 11:51
    
Tinkering with the counters is not the way to go i think. I prefer to use implemented features. –  Loofmann Feb 16 '13 at 12:34

Move the main label and \caption to the end of the figure environment.

\documentclass{scrartcl}

\usepackage[demo]{graphicx}
\usepackage{subfig}

\begin{document}
    \begin{figure}
        \subfloat[first picture]{
            \includegraphics[width=5cm]{name}
            \label{img:first}
        }
        \subfloat[second picture]{
            \includegraphics[width=5cm]{name}
            \label{img:second}
        }
        \caption{Two pictures side by side}
        \label{img:both}
    \end{figure}

    This example shows that figure \ref{img:second} has a wrong reference number.
    But the complete float is referenced correctly: \ref{img:both}
\end{document}
share|improve this answer
    
Hi Ian, thanks for the suggestion but I prefer the caption on top of the figures because I use the hyperref package. When I click on the link which a reference produces my pdf viewer moves to the figure in a way that aligns the caption at the top. Therefore i have to scroll up to this the figure. –  Loofmann Feb 16 '13 at 12:26

I moved the caption and the label for the figure environment to the bottom and that solved the problem for me. Below is my MWE with the output.

\documentclass{scrartcl}

\usepackage[demo]{graphicx}
\usepackage{subfig}

\begin{document}
    \begin{figure}
        \subfloat[first picture]{
            \includegraphics[width=5cm]{name}
            \label{img:first}
        }
        \subfloat[second picture]{
            \includegraphics[width=5cm]{name}
            \label{img:second}
        }
        \caption{Two pictures side by side}
        \label{img:both}
    \end{figure}

    This example shows that figure \ref{img:second} has a wrong reference number.
    But the complete float is referenced correctly: \ref{img:both}
\end{document}

enter image description here

share|improve this answer
    
Hi Umar, its working indeed but I like my caption above the figure. See my comment on the post ahead for more infos. –  Loofmann Feb 16 '13 at 12:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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