22

I'd like to put subfigure labels (a), (b), etc., at the top left corner of subfigures like the following figure:

image

I know there are some workarounds like this post (with stackengine) or this post (with subcaption). However, I don't want to use stackengine unless there's really no way to do so, and REVTeX4 rules out the subcaption option. I therefore wonder if there exists a workaround specifically for subfig package (and potentially compatible with REVTeX4).

The following MWE provides an unsuccessful attempt to achieve the desired effect:

\documentclass{revtex4-1}
\usepackage{graphicx}
\usepackage{subfig}
\captionsetup[subfloat]{farskip=-10pt, position=top}

\begin{document}
\begin{figure}
\centering
    \subfloat[][]{
    \includegraphics[width=0.45\linewidth]{example-image-a}}
    \subfloat[][]{
    \includegraphics[width=0.45\linewidth]{example-image-b}}\\
    \subfloat[][]{
        \includegraphics[width=0.45\linewidth]{example-image-c}}
    \subfloat[][]{
        \includegraphics[width=0.45\linewidth]{example-image-a}}
    \caption{abcd}
\end{figure}
\end{document}
  • 2
    This question is very similar to Subfigures with number inside figure. Does it answer your question? – Werner Aug 18 '13 at 17:15
  • 1
    @Werner, it did, but as I mentioned in the post, I'm looking for other possible workarounds because I'm not sure if the journal publisher accepts tex files which include the stackengine package. – Leo Fang Aug 18 '13 at 17:31
  • @Werner, another reason I don't like the answer in that post is that I want LaTeX to take care the typeset, including subfigures. If I can pre-process my figure like the example shown in that question, honestly speaking I can also insert a subfigure label using external software. Then why bother to do that with LaTeX? – Leo Fang Aug 18 '13 at 17:36
  • 1
    Also, welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. – Sean Allred Aug 18 '13 at 17:37
17

I'd suggest writing your own macro to place the sub-figure numbering:

enter image description here

\documentclass{revtex4-1}% http://ctan.org/pkg/ltxutil
\usepackage{graphicx}% http://ctan.org/pkg/graphicx
\newcommand{\subfigimg}[3][,]{%
  \setbox1=\hbox{\includegraphics[#1]{#3}}% Store image in box
  \leavevmode\rlap{\usebox1}% Print image
  \rlap{\hspace*{10pt}\raisebox{\dimexpr\ht1-2\baselineskip}{#2}}% Print label
  \phantom{\usebox1}% Insert appropriate spcing
}
\begin{document}
\begin{figure}
  \centering
  \begin{tabular}{@{}p{0.45\linewidth}@{\quad}p{0.45\linewidth}@{}}
    \subfigimg[width=\linewidth]{A)}{example-image-a} &
    \subfigimg[width=\linewidth]{B)}{example-image-b} \\
    \subfigimg[width=\linewidth]{C)}{example-image-c} &
    \subfigimg[width=\linewidth]{D)}{example-image-a}
  \end{tabular}
  \caption{A caption}
\end{figure}
\end{document}

Once you have the image, you can print it in a box and extract its dimensions in order to use them to position the label.

The above macro \subfigimg[<options>]{<label>}{<image>} does exactly that. It inserts <image> with options <options> and imprints the <label> 10pt from the left and 2 baseline skips from the top of the image.

No packages nor tomfoolery. Just box manipulation.


Some added flair with string comparison for positioning...

pdfTeX introduced \pdfstrcmp for string comparison in version 1.30:

\pdfstrcmp{<a>}{<b>} compares two strings and returns the strings "0" if equals <b>, "-1" if <a> is less than <b>, "1" if <a> is greater than <b>.

enter image description here

\documentclass{revtex4-1}% http://ctan.org/pkg/ltxutil
\usepackage{graphicx}% http://ctan.org/pkg/graphicx
\usepackage{xkeyval,xcolor}% http://ctan.org/pkg/{xkeyval,xcolor}
\makeatletter
\newlength{\sfp@hseplen}\newlength{\sfp@vseplen}
\define@cmdkey{subfigpos}[sfp@]{pos}[ul]{}% \sfp@pos
\define@cmdkey{subfigpos}[sfp@]{font}[\small]{}% \sfp@font
\define@cmdkey{subfigpos}[sfp@]{vsep}[2\baselineskip]{\setlength{\sfp@vseplen}{\sfp@vsep}}% \sfp@vsep
\define@cmdkey{subfigpos}[sfp@]{hsep}[10pt]{\setlength{\sfp@hseplen}{\sfp@hsep}}% \sfp@hsep
\newcommand{\subfigimg}[3][,]{%
  \setkeys{Gin,subfigpos}{pos,font,vsep,hsep,#1}% Set (default) keys
  \setbox1=\hbox{\includegraphics{#3}}% Store image in box
  \ifnum\pdfstrcmp{\sfp@pos}{ul}=0% UPPER LEFT placement of subfig label
    \leavevmode\rlap{\usebox1}% Print image
    \rlap{\hspace*{\sfp@hsep}\raisebox{\dimexpr\ht1-\sfp@vsep}{\sfp@font{#2}}}% Print label
    \phantom{\usebox1}% Insert appropriate spacing
  \else\ifnum\pdfstrcmp{\sfp@pos}{ur}=0% UPPER RIGHT placement of subfig label
    \leavevmode\usebox1% Print image
    \llap{\raisebox{\dimexpr\ht1-\sfp@vsep}{\sfp@font{#2}}\hspace*{\sfp@hsep}}% Print label
  \else\ifnum\pdfstrcmp{\sfp@pos}{lr}=0% LOWER RIGHT placement of subfig label
    \leavevmode\usebox1% Print image
    \llap{\raisebox{\sfp@vsep}{\sfp@font{#2}}\hspace*{\sfp@hsep}}% Print label
  \else% Assume LOWER LEFT placement of subfig label
    \leavevmode\rlap{\usebox1}% Print image
    \rlap{\hspace*{\sfp@hseplen}\raisebox{\sfp@vsep}{\sfp@font{#2}}}% Print label
    \phantom{\usebox1}% Insert appropriate spacing
  \fi\fi\fi
}
\makeatother
\begin{document}
\begin{figure}
  \centering
  \begin{tabular}{@{}p{0.45\linewidth}@{\quad}p{0.45\linewidth}@{}}
    \subfigimg[width=\linewidth,pos=lr]{A)}{example-image-a} &
    \subfigimg[width=\linewidth,pos=ll,font=\color{green!30!red}]{B)}{example-image-b} \\
    \subfigimg[width=\linewidth,pos=ur,font=\LARGE]{C)}{example-image-c} &
    \subfigimg[width=\linewidth,pos=ul]{D)}{example-image-a}
  \end{tabular}
  \caption{A caption}
\end{figure}
\end{document}

The above MWE adds the keys pos, font, hsep and vsep to the mix. In turn they allow for selecting the position of the label, which font to use, the horizontal separation and vertical separation.

  • This is as awesome as another answer Werner! It's hard for me to decide which one I should accept :( – Leo Fang Aug 19 '13 at 21:58
  • For those who don't want to use the tabular environment: the macro defined by Werner is compatible with the subfig package. Just pretend the whole \subfigimg object as if it were \includegraphics and do \begin{figure} \centering \subfloat{\subfigimg[width=0.45\linewidth]{(a)}{example-image-a}}\quad \subfloat{\subfigimg[width=0.45\linewidth]{(b)}{example-image-b}} \ \subfloat{\subfigimg[width=0.45\linewidth]{(c)}{example-image-c}}\quad \subfloat{\subfigimg[width=0.45\linewidth]{(d)}{example-image-a}} \caption{abcd} \end{figure} – Leo Fang Aug 20 '13 at 20:28
  • is there a precise way to control the font size of the label? – Leo Fang Aug 21 '13 at 15:28
  • 1
    @LeoFang: Yes; the label is argument #2 in \subfigimg{#1}{#2}{#3}. So, add whatever you want before/around #2 in the definition. For example, \Large #2 would set the label in \Large font; \textbf{\textit{#2}} would set a bold italicized label... – Werner Aug 21 '13 at 15:59
  • 1
    @math: See the updated answer which now adds 4 different keys for label placement/font/separation. – Werner Sep 5 '13 at 7:16
7

As the author of stackengine and the provider of a solution on Subfigures with number inside figure, I should be a bit loathe to undercut myself and provide an alternative solution. But here it is (we're all in it together). Not nearly as elegant, quite brute force, but it avoids use of the package.

EDITED to remove vestigial part of the solution.

\documentclass{article}
\usepackage{graphicx}
\begin{document}
xxx

\includegraphics[width=5in]{vjbrp}\llap{
  \parbox[b]{4.5in}{(A)\\\rule{0ex}{2.2in}
  }}

yyy
\end{document} 

enter image description here

  • Thanks Steven! It works with my TeX file after manually fine tune the parameters. This is indeed quite brute force, but so is the answer you provided with stackengine, so I still like this one more. However I'm not quite sure why you need \hspace{4.0in} after (a). I thought the horizontal and vertical position of (a) is tuned by where 4.5in and 2.2in is, respectively. Do I get it right? – Leo Fang Aug 19 '13 at 4:18
  • 1
    @LeoFang, the \hspace is vestigial from when I tried a solution without a \parbox. You are right, it should be removed, and I will do so. – Steven B. Segletes Aug 19 '13 at 18:34
  • 1
    @LeoFang As a follow up, yes, tuning the 4.5in and 2.2in will allow horizontal and vertical adjustment, respectively. – Steven B. Segletes Aug 19 '13 at 18:50
  • Hi Steven, I found myself confused about the position of the box being overlaid. When using \llap to put the label on top of the figure, where is the baseline? I'm asking this because I found when moving the label horizontally to the left, I need to increase rather than decrease the value 4.5in, which is a little bit counterintuitive. I guess the reason is that it's \llap being used, not \rlap. By the way, since \hspace has no effect here, how do I tune the font size of the label? – Leo Fang Aug 19 '13 at 22:44
  • 1
    @LeoFang The inset label must be applied after the image is rendered (so as not to be covered by it). Thus, the "cursor" position at the time of rendering is on the right-hand side of the image. If the image was placed with \includegraphics, the baseline of the \llap will be the bottom (right-hand corner) of the image. Thus, increasing the size of the \parbox` moves the inset label to the left. Likewise, the \parbox positioning must be [b] to be aligned with that, and the \rule commencing on the second line of the parbox lifts the inset upward. I prefer stackengine approach. – Steven B. Segletes Aug 19 '13 at 23:26

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.