1

I'm using pgfplots with tikz's external library for my graphics, and I must use the subfigure package for compliancy reasons.

As you can see in the mwe below (part "Attempt 1"), inside a figure* environment (which I must use) I place two small subfigures, and I would like the legend (common to both figures) to be between them, possibly at mid-height. However, even though I tried various legend position specifications, no matter what I do the legend doesn't move by a single millimetre.

\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[pdftex]{graphicx}
\graphicspath{{./img/}}
\DeclareGraphicsExtensions{.pdf}
\usepackage{subfigure}
\usepackage{pgfplots}
\usetikzlibrary{external}
\tikzexternalize
\tikzsetexternalprefix{tikzpics/}
\pgfplotsset{compat=newest, every mark/.append style={mark size=1pt, mark line=solid}}
\begin{document}

%%%%%%%%% Attempt 1

\begin{figure*}[t!]
\centering
\subfigure[First]{
\begin{tikzpicture}
    \begin{axis}[width=0.4\textwidth,xlabel={X axis}, ylabel={Y axis},]
        \addplot [blue, mark=diamond*, densely dashed, ultra thick, mark options={solid,scale=1.5}] coordinates {(-0.5,-1) (1,1)};
        \addplot [green, mark=*, ultra thick] coordinates {(-0.5,-0.9) (1,1.1)};
        \addplot [red, mark=square*, dotted, ultra thick] coordinates {(-0.5,-1.1) (1,0.9)};
    \end{axis}
\end{tikzpicture}}\hfil
\subfigure{
\begin{tikzpicture}
\begin{axis}[width=0.2\textwidth, height=0.2\textwidth, hide axis, xmin=0, xmax=10, ymin=0, ymax=0.2,legend columns=1,
            legend style={draw=white!15!black,legend cell align=left, at={(0.5,0.5)}},]
    \addlegendimage{blue, mark=diamond*, densely dashed, ultra thick, mark options={solid,scale=1.5}}
    \addlegendentry{Trace 1}
    \addlegendimage{green, mark=*, ultra thick}
    \addlegendentry{Trace 2}
    \addlegendimage{red, mark=square*, dotted, ultra thick, mark options={solid,scale=1.5}}
    \addlegendentry{Trace 3}
\end{axis}
\end{tikzpicture}}\hfil
\subfigure[Second]{
\begin{tikzpicture}
    \begin{axis}[width=0.4\textwidth,xlabel={X axis}, ylabel={Y axis},]
        \addplot [blue, mark=diamond*, densely dashed, ultra thick, mark options={solid,scale=1.5}] coordinates {(-0.5,-1) (1,1)};
        \addplot [green, mark=*, ultra thick] coordinates {(-0.5,-0.9) (1,1.1)};
        \addplot [red, mark=square*, dotted, ultra thick] coordinates {(-0.5,-1.1) (1,0.9)};
    \end{axis}
\end{tikzpicture}}
\caption{Caption.}
\end{figure*}

%%%%%%%%% Attempt 2

\begin{figure*}[t!]
\centering
\subfigure[First]{
\begin{tikzpicture}
    \begin{axis}[width=0.4\textwidth,xlabel={X axis}, ylabel={Y axis}, legend style={overlay, at={(1.2,0.5)},anchor={north}}]
        \addplot [blue, mark=diamond*, densely dashed, ultra thick, mark options={solid,scale=1.5}] coordinates {(-0.5,-1) (1,1)};
        \addplot [green, mark=*, ultra thick] coordinates {(-0.5,-0.9) (1,1.1)};
        \addplot [red, mark=square*, dotted, ultra thick] coordinates {(-0.5,-1.1) (1,0.9)};
        \legend{Trace 1, Trace 2, Trace 3};
    \end{axis}
\end{tikzpicture}}\hfil
\subfigure[Second]{
\begin{tikzpicture}
    \begin{axis}[width=0.4\textwidth,xlabel={X axis}, ylabel={Y axis},]
        \addplot [blue, mark=diamond*, densely dashed, ultra thick, mark options={solid,scale=1.5}] coordinates {(-0.5,-1) (1,1)};
        \addplot [green, mark=*, ultra thick] coordinates {(-0.5,-0.9) (1,1.1)};
        \addplot [red, mark=square*, dotted, ultra thick] coordinates {(-0.5,-1.1) (1,0.9)};
    \end{axis}
\end{tikzpicture}}
\caption{Caption.}
\end{figure*}

\end{document}

Attempt 1

As a second attempt, I tried to use the overlay option of the axis environment (see part "Attempt 2" in the mwe above). This time, I see that the subfigure environment clips away the portion of the legend which lies outside the plot (see image below), and I can't seem to find any option to avoid this.

Attempt 2

Just to mention it, I also gave a try to using pgfplots' option legend to name+\ref, but even by playing with the various options for externalization I could not succeed.

Any suggestion is welcomed, thanks in advance.

DavideM
  • 181
  • As you have seen from the low response so far, to fulfill your wish(es) is not that easy. But I think that is not the only reason why the response is that low. I (personally) think that it is not a good idea to solve your problem with your suggested wish. I would recommend to add a legend to the rightmost axis using legend pos=outer north east. By that you avoid the problem of your attempt 1 which will resulted in sublabels (a) and (c) (instead of (b)) and the need to manually shift the "extra" legend up(wards) ... – Stefan Pinnow Aug 19 '19 at 12:40
  • ... The downside is that the subcaption of the mostright plot is then centered below the axis and the legend, which might not look that good or "as expected". Another downside might be, that it is unclear if the legend applies only to that or also to all the other plots (of that figure environment). If that should be unclear I suggest adding a note to the (main) caption. – Stefan Pinnow Aug 19 '19 at 12:42
  • @StefanPinnow Thanks for the hint. Of course it works, but it shows both the downsides you already pointed out. Even adding the outside legend to the left plot doesn't result in much of a better work, because then I have to manually adjust the position of the right plot in order to display the legend exactly between the two. I didn't expect the solution to be that easy, but not to be so hard either; I thought there would be just some command or "trick" I didn't know about. Thanks anyway. – DavideM Aug 20 '19 at 06:22
  • Hopefully you agree that when the legend is placed between the plots it is also not clear to which of the both plots the legend belongs or if it belongs to both ... So basically "your" and "my" attempt have one different downside. – Stefan Pinnow Aug 20 '19 at 06:30
  • I assume to overcome "my" (remaining) downside there can be found a trick thus that either the legend is not accounted for in the bounding box or the subcaption can be shifted/manipulated thus that it looks again that it is centered below the plot (without the legend). So if this would be an option, let us know. – Stefan Pinnow Aug 20 '19 at 06:32
  • @StefanPinnow Actually, I deem that if the legend is well placed between the two plots it implies that it's referring to both, therefore my attempts; but I guess this is rather a subjective matter. Thanks for the further hint, I'll take some time to think about it, and of course if I succeed I'll let you all know. – DavideM Aug 20 '19 at 07:17
  • Based on the above comments and reading some comments to an old question, I found some sort of workaround: Firstly, starting from "Attempt 1", I remove the middle subfigure so that the tikzpicture with the legend is "standalone" (so now the second plot is correctly labelled (b), thanks @StefanPinnow); secondly, I put the legend inside \raisebox{Xcm}{} to adjust its vertical position. I can now obtain what I wanted, but still doesn't seem an optimal solution – DavideM Aug 20 '19 at 11:10

1 Answers1

3

You could use the baseline option to the tikzpictures, seems to work for externalized graphics as well. I add name=ax to the axis options (or legend style), and use baseline=(ax.center) for all three. I also removed the \subfigure{} around the middle tikzpicture, as it's not needed.

As an addendum, in a case like this it could be useful to make a custom cycle list, then you don't have to duplicate the plot styles three times over.

enter image description here

\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[pdftex]{graphicx}
\graphicspath{{./img/}}
\DeclareGraphicsExtensions{.pdf}
\usepackage{subfigure}
\usepackage{pgfplots}
\usetikzlibrary{external}
\tikzexternalize
\tikzsetexternalprefix{tikzpics/}
\pgfplotsset{
  compat=newest,
  every mark/.append style={mark size=1pt, mark line=solid},
}
% create a custom cycle list:
\pgfplotscreateplotcyclelist{MyList}{
blue, mark=diamond*, densely dashed, ultra thick, mark options={solid,scale=1.5}\\
green, mark=*, ultra thick\\
red, mark=square*, mark options={solid}, mark size=3pt,dotted, ultra thick\\
}
\begin{document}


\begin{figure*}
\centering
\subfigure[First]{
\begin{tikzpicture}[baseline=(ax.center)] % <-- added baseline
    \begin{axis}[
      name=ax, % added
      cycle list name=MyList, % added
      width=0.4\textwidth,
      xlabel={X axis},
      ylabel={Y axis}
]
        \addplot coordinates {(-0.5,-1) (1,1)};
        \addplot coordinates {(-0.5,-0.9) (1,1.1)};
        \addplot coordinates {(-0.5,-1.1) (1,0.9)};
    \end{axis}
\end{tikzpicture}}\hfil
\begin{tikzpicture}[baseline=(leg.center)] % <-- added baseline
\begin{axis}[
   cycle list name=MyList, % added
   width=0.2\textwidth, height=0.2\textwidth,
   hide axis,
   xmin=0, xmax=10, ymin=0, ymax=0.2,
   legend columns=1,
   legend style={ 
     name=leg, % added
     draw=white!15!black,
     legend cell align=left,
      at={(0.5,0.5)}
     }]

    % add three dummy plots, the single point is outside the axis limits, so not shown
    \pgfplotsinvokeforeach{1,2,3}{\addplot coordinates {(0,-1)};}
    \addlegendentry{Trace 1}
    \addlegendentry{Trace 2}
    \addlegendentry{Trace 3}
\end{axis}
\end{tikzpicture}\hfil
\subfigure[Second]{
\begin{tikzpicture}[baseline=(ax.center)] % <-- added baseline option
    \begin{axis}[
       name=ax,  % added
       cycle list name=MyList, % added
       width=0.4\textwidth,
       xlabel={X axis}, ylabel={Y axis},
     ]
        \addplot coordinates {(-0.5,-1) (1,1)};
        \addplot coordinates {(-0.5,-0.9) (1,1.1)};
        \addplot coordinates {(-0.5,-1.1) (1,0.9)};
    \end{axis}
\end{tikzpicture}}
\caption{Caption.}
\end{figure*}
\end{document}
Torbjørn T.
  • 206,688