1

I'm working on a LaTeX template, the elsarticle class from Elsivier, where I have two subfigures created using the subcaption package. I came across this answer which provides a solution for having a common legend for subfigures, but it uses the subfigure package. Unfortunately, I've already utilized the subcaption package for previous figures in my draft.

When I attempt to integrate the provided code into my document, I encounter errors like the ones shown in this image. enter image description here

I suspect these errors may stem from conflicts between the subfigure and subcaption packages.

My main question is: How can I modify the code to have a single common legend for both subfigures while using the subcaption package?

Here's the code snippet generating the figures:

\documentclass[preprint,3p,number]{elsarticle}

\usepackage{amssymb}
\usepackage[breaklinks=true,colorlinks,bookmarks=true]{hyperref}
\usepackage[inline]{enumitem}
\usepackage{times}
\usepackage{comment}
\usepackage{epsfig}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{algorithm}
\usepackage{algpseudocode}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{enumitem}
\setitemize{noitemsep,topsep=0pt,parsep=0pt,partopsep=0pt}
\usepackage{subcaption}

\begin{document}

\begin{frontmatter}

%% Title, authors and addresses
\title{2 subfigures with 1 common legend}



\begin{abstract}

\end{abstract}



\begin{keyword}
% keywords here, in the form: keyword \sep keyword


\end{keyword}

\end{frontmatter}

%% main text

\begin{figure}[ht!]
\begin{subfigure}{0.48\textwidth}
\begin{tikzpicture}
\begin{axis}[
    ybar=0pt,
    enlargelimits=0.15,
    width=\columnwidth,
    ymin=90,
    ylabel={Accuracy (\%)},
    symbolic x coords={VGG,GoogLeNet,DenseNet,ResNet},
    xtick=data,
    bar width=10pt,
    legend style={ 
        at={(0.5,-0.15)},
        anchor=north,
        legend columns=-1,
    },
    axis x line*=bottom,
    axis y line*=left,
]
\addplot [blue, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.86) (GoogLeNet, 95.22) (DenseNet, 94.85) (ResNet, 93.98)};
\addplot [green, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.81) (GoogLeNet, 95.3) (DenseNet, 94.45) (ResNet, 93.97)};
\addplot [red, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.86) (GoogLeNet, 95.09) (DenseNet, 94.53) (ResNet, 94.17)};
\legend{Cosine, Euclide, VBD}
\end{axis}
\end{tikzpicture}
\caption{CIFAR-10.}
\label{subfig:cifar10}
\end{subfigure}
%------------------------------------------------------------------------
\qquad
\begin{subfigure}{0.48\textwidth}
\begin{tikzpicture}
\begin{axis}[
    ybar=0pt,
    enlargelimits=0.15,
    width=\columnwidth,
    ymin=90,
    ylabel={Accuracy (\%)},
    symbolic x coords={VGG,GoogLeNet,DenseNet,ResNet},
    xtick=data,
    bar width=10pt,
    legend style={ 
        at={(0.5,-0.15)},
        anchor=north,
        legend columns=-1,
    },
    axis x line*=bottom,
    axis y line*=left,
]
\addplot [blue, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.86) (GoogLeNet, 95.22) (DenseNet, 94.85) (ResNet, 93.98)};
\addplot [green, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.81) (GoogLeNet, 95.3) (DenseNet, 94.45) (ResNet, 93.97)};
\addplot [red, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.86) (GoogLeNet, 95.09) (DenseNet, 94.53) (ResNet, 94.17)};
\legend{Cosine, Euclide, VBD}
\end{axis}
\end{tikzpicture}
\caption{CIFAR-100.}
\label{subfig:cifar100}
\end{subfigure}
\caption{Ablation study on distance metrics.}
\label{fig:criteria_comparison}
\end{figure}

\end{document}

It generates this figure: enter image description here

Here's a link for reproduction.

I'd like the legend to be at the bottom of the figure, between two subfigures. Here's my expected output using Paint: enter image description here

I appreciate any help or suggestions. Thank you!

6
  • If you could do that: where would you like to place the common legend?
    – MS-SPO
    Commented Jan 21 at 21:36
  • \label statements must come after \caption statements.
    – Mico
    Commented Jan 22 at 0:38
  • Please tell us which document class you employ and which packages need to be loaded to make your code compilable. Thanks.
    – Mico
    Commented Jan 22 at 0:39
  • Your main question, "How can I modify the code to have a single common legend for both subfigures while using the subcaption package?", is unclear. For sure, your code already contains an overall caption that applies to both subfigure environments. Are you maybe asking how to get rid of subfigure captions, viz. CIFAR-10. and CIFAR-100.? Is something stopping you from deleting the associate \caption directives?
    – Mico
    Commented Jan 22 at 0:47
  • Hi @Mico, I've modified the question as per your suggestion. Please consider reviewing it. Thank you very much.
    – Tien
    Commented Jan 22 at 8:42

2 Answers 2

2

This question doesn't look as a real subfigure question, but a tikz/pgfplots question.

New answer According to pgfplots manual:

4.9.7 Legends Outside Of an Axis

you can use the:

legend to name={<name>}

option in the first axis and no legend in the second one. This option doesn't draw the legend but store its code.

This code is then executed when you use \ref{<name>}. This command can be used even outside of any tikzpicture, usually just before the main figure's \caption.

Use \centering command at the beginning of figure environmemt to get it centered, as well as the subfigures.

Old answer:

If you don't absolutly need to \refer separately CIFAR-10 and CIFAR-100 (using e.g.\ref{fig:criteria_comparison}-left or -right), here is a possible workaround :

  1. Suppress the sufigures and the subcaptions.
  2. Merge the two tikzpictures into a single one, containing two axis environments.
  3. Put the secondaxis in a scope with the suitable xshift=... option
  4. Modify the anchor of the legend (at=...) in the first axis` and suppress it in the second one.
  5. Optionally, add the suppressed subcaptions as TikZ nodes in the corresponding axis or scope.
2
  • The second answer of @Jhor works with me. Thank you very much! Note that when putting \centering command at the beginning of figure, one should remove \qquad so that the subfigures stay in 1 row.
    – Tien
    Commented Jan 22 at 11:15
  • 1
    I fear that the line break between the two subfigures doesn't come from the \centering but from another thing, most probably too wide tikz pictures, or white line between them. Anyway, it is recommanded to use \hfill or \hfil instead of \quad or \qquad to separate the two parts. And put a % at the end of lines containong only spacing commands.
    – Jhor
    Commented Jan 24 at 8:54
0

Here's a possible solution, suggested by @Jhor, just post in in case someone need the code:

\begin{figure}[ht!]
\centering
\begin{subfigure}{0.48\textwidth}
\begin{tikzpicture}
\begin{axis}[
    ybar=0pt,
    enlargelimits=0.15,
    width=\columnwidth,
    ymin=90,
    ylabel={Accuracy (\%)},
    symbolic x coords={VGG,GoogLeNet,DenseNet,ResNet},
    xtick=data,
    bar width=10pt,
    legend style={ 
        at={(0.5,-0.15)},
        anchor=north,
        legend columns=-1,
    },
    legend to name={mylegend},
    axis x line*=bottom,
    axis y line*=left,
]
\addplot [blue, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.86) (GoogLeNet, 95.22) (DenseNet, 94.85) (ResNet, 93.98)};
\addplot [green, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.81) (GoogLeNet, 95.3) (DenseNet, 94.45) (ResNet, 93.97)};
\addplot [red, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.86) (GoogLeNet, 95.09) (DenseNet, 94.53) (ResNet, 94.17)};
\legend{Cosine, Euclide, VBD}
\end{axis}
\end{tikzpicture}
\caption{CIFAR-10.}
\label{subfig:cifar10}
\end{subfigure}
\hfill
%------------------------------------------------------------------------
\begin{subfigure}{0.48\textwidth}
\begin{tikzpicture}
\begin{axis}[
    ybar=0pt,
    enlargelimits=0.15,
    width=\columnwidth,
    ymin=90,
    ylabel={Accuracy (\%)},
    symbolic x coords={VGG,GoogLeNet,DenseNet,ResNet},
    xtick=data,
    bar width=10pt,
    legend style={ 
        at={(0.5,-0.15)},
        anchor=north,
        legend columns=-1,
    },
    axis x line*=bottom,
    axis y line*=left,
]
\addplot [blue, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.86) (GoogLeNet, 95.22) (DenseNet, 94.85) (ResNet, 93.98)};
\addplot [green, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.81) (GoogLeNet, 95.3) (DenseNet, 94.45) (ResNet, 93.97)};
\addplot [red, fill, opacity=0.7, nodes near coords,every node near coord/.append style={xshift=5pt,yshift=12pt,font=\footnotesize,rotate=90, opacity=1}]coordinates {(VGG, 93.86) (GoogLeNet, 95.09) (DenseNet, 94.53) (ResNet, 94.17)};
\end{axis}
\end{tikzpicture}
\caption{CIFAR-100.}
\label{subfig:cifar100}
\end{subfigure}
\ref{mylegend}
\caption{Ablation study on distance metrics.}
\label{fig:criteria_comparison}
\end{figure}
2
  • 1
    I think you're missing an \hfill directive immediately after the first \end{subfigure} directive. Also, the \centering instruction after \begin{figure}[ht!] isn't needed.
    – Mico
    Commented Jan 22 at 11:38
  • 1
    @Mico I've added the \hfill to the answer. I also tested, without \centering, the common legend will be left-aligned.
    – Tien
    Commented Jan 22 at 15:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .