2

I have a figure that should be centered and contain three plots. One at the top, one at the bottom-left and one at the bottom-right. I used one tikzpicture with a regular begin{axis} for the top plot and a begin{groupplot} for the bottom plots. The legend for the bottom plots should be centered above the two bottom plots / below the upper plot.

\documentclass{article}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{figure*}[ht!]
    \centering
    \begin{tikzpicture}%[trim axis left, trim axis right, trim axis group left, trim axis group right]
    \begin{axis}[%
        name=plota,
        height=0.35\textwidth,
        legend style={
            anchor=south,
            at={(current bounding box.north-|current axis.north)},
            legend columns=2
        },
        ybar,
        x=25mm,
        ylabel={ylabel}
    ]
        \addplot[] coordinates { (0, 1) (1,2) (2,4) (3,8) };
        \addplot[] coordinates { (0, 1) (1,3) (2,9) (3,27) };
        \addlegendentry{2}
        \addlegendentry{3}
    \end{axis}
    \node[text width=.45\linewidth,align=center,anchor=north](subfiga) at (plota.below south) {subfigure text a};
    \begin{groupplot}[group style={group size=2 by 1, group name=mygroup},
        height=.375\linewidth,
        log basis x={2},
        xlabel={Width (bytes)},
    ]
    \nextgroupplot[
        name=plotb,
        at={(plota.below south west|-subfiga.south west)},
        yshift=-8mm,
        anchor=north west,
        legend to name={legend2},
        ylabel={ylabel}
    ]
        \addlegendentry{3}
        \addlegendentry{4}
        \addplot[] coordinates { (2,2) (4,5) };
        \addplot[] coordinates { (2,5) (4,7) };
    \nextgroupplot[
        name=plotc,
        at={(plota.below south east|-subfiga.south east)},
        anchor=north east,
        yticklabel pos=upper,
        yshift=-8mm,
    ]
        \addplot[] coordinates { (2,3) (4,2) };
        \addplot[] coordinates { (2,2) (4,3) };
    \end{groupplot}
    \path (plotb.above north west)-- coordinate(legendpos) (plotc.above north east);
    \node[align=center,anchor=south](legend) at (legendpos) {\ref{legend2}};

    \node[text width=.45\linewidth,align=center,anchor=north] at
        (plotb.below south) {subfigure text b};
    \node[text width=.45\linewidth,align=center,anchor=north] at
        (plotc.below south) {subfigure text c};
    \end{tikzpicture}
    \caption{caption}
\end{figure*}
\end{document}

The figure in itself basically works (but the axis is not centered with respect to the page), as long as I don't specify any of the trim axis options. If I specify all of them, the picture is centered, but the legend is off. If I specify just trim axis left and trim axis right, all hell breaks loose (i.e. the whole picture is off-center and the legend is off):

tikz picture with trim axis options

(ignore the legend overlapping the "subfigure a" text, I will resolve that with a yshift)

Plus, I get the following error that I don't understand, regardless of the axis trim options specified.


! Package pgf Error: No shape named mygroup c1r1 is known.

See the pgf package documentation for explanation.
Type  H   for immediate help.
 ...                                              

l.54        ]

Edit: Using alias instead of name fixes this warning (thanks to user marmot). Is alias documented anywhere?

Edit: This question seems related, although I wasn't able to implement the answer for the problem at hand.

apriori
  • 953
  • 1
    <pre><code> seems broken. I edited the question to use space-indentation to format the code now. – apriori Jan 21 '19 at 18:35
  • The only occurences of trim I find in your code are in %[trim axis left, trim axis right, trim axis group left, trim axis group right], which is commented out. On the other hand, you state that "It basically works, as long as I don't specify any of the trim axis options.". What do I have to do to get no errors? –  Jan 21 '19 at 18:38
  • It basically works means that it works as expected (minus the error message). I want the axis of the upper plot to be centered to the page. So I tried the axis trim options. And they seem to mess things up for me. – apriori Jan 21 '19 at 18:41

1 Answers1

1

This produces something in which the legend is positioned where I think you want to have it. I didn't touch the trims because I do not understand what you want to do with them. What I did is:

  1. Replaced name=plotb and name=plotc to alias=plotb and alias=plotc to get rid of the error message ! Package pgf Error: No shape named mygroup c1r1 is known.
  2. Added midway to the legendpos coordinate to have the legend in the middle.

\documentclass{article}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{figure*}[ht!]
    \centering
    \begin{tikzpicture}%[trim axis left, trim axis right, trim axis group left, trim axis group right]
    \begin{axis}[%
        name=plota,
        height=0.35\textwidth,
        legend style={
            anchor=south,
            at={(current bounding box.north-|current axis.north)},
            legend columns=2
        },
        ybar,
        x=25mm,
        ylabel={ylabel}
    ]
        \addplot[] coordinates { (0, 1) (1,2) (2,4) (3,8) };
        \addlegendentry{2}
        \addplot[] coordinates { (0, 1) (1,3) (2,9) (3,27) };
        \addlegendentry{3}
    \end{axis}
    \node[text width=.45\linewidth,align=center,anchor=north](subfiga) at (plota.below south) {subfigure text a};
    \begin{groupplot}[group style={group size=2 by 1, group name=mygroup},
        height=.375\linewidth,
        log basis x={2},
        xlabel={Width (bytes)},
    ]
    \nextgroupplot[
        alias=plotb,
        at={(plota.below south west|-subfiga.south west)},
        yshift=-12mm,
        anchor=north west,
        legend to name={legend2},
        ylabel={ylabel}
    ]
        \addplot[] coordinates { (2,2) (4,5) };
        \addlegendentry{3}
        \addplot[] coordinates { (2,5) (4,7) };
        \addlegendentry{4}
    \nextgroupplot[
        alias=plotc,
        at={(plota.below south east|-subfiga.south east)},
        anchor=north east,
        yticklabel pos=upper,
        yshift=-12mm,
    ]
        \addplot[] coordinates { (2,3) (4,2) };
        \addplot[] coordinates { (2,2) (4,3) };
    \end{groupplot}
    \path (plotb.above north west)-- (plotc.above north east) 
    coordinate[midway](legendpos) ;
    \node[align=center,anchor=south](legend) at (legendpos) {\ref{legend2}};

    \node[text width=.45\linewidth,align=center,anchor=north] at
        (plotb.below south) {subfigure text b};
    \node[text width=.45\linewidth,align=center,anchor=north] at
        (plotc.below south) {subfigure text c};
    \end{tikzpicture}
    \caption{caption}
\end{figure*}
\end{document}

enter image description here

  • Without the trim axis options, the plot itself is not centered on the page, it's bounding box (including e.g. yticks) is. I need the plot to be centered. The legend is only not centered with the trim axis options. I can confirm that using alias instead of name gets rid of the error message – apriori Jan 21 '19 at 19:55
  • @apriori Sorry, was offline. I see that you answered your own question, and deleted your answer. To answer your question contained in your answer: Yes, if you use legend to name, a self-contained picture will be created that can be used outside the current TikZ picture. Whether or not it is always safe to use it inside the node of another TikZ picture, I do not know by heart, but this is something that can be found out by looking at the source code. (You want to avoid nesting tikzpicture environments.) –  Jan 22 '19 at 00:18
  • Although starting a new tikzpicture worked at first, porting the MWE back to my actual document shifted them to the right (without an overfull hbox warning). I'm currently looking into that. – apriori Jan 22 '19 at 00:46
  • Well, it is hard to respond to that because I do not know what you concretely tried. (Sometimes one can use the \centerline primitive in such cases.) –  Jan 22 '19 at 00:50
  • The original question is still valid. I suspect that using trim axis group left and trim axis group right together with groupplots and a shared legend is just broken. – apriori Jan 22 '19 at 01:00
  • @apriori What is wrong with two separate tikzpictures? –  Jan 22 '19 at 01:12
  • When I tried two separate tikzpictures, I used trim axis left / trim axis right on the upper one and trim axis group left / trim axis group right on the lower one. The lower one still had the botched legend location. – apriori Jan 22 '19 at 01:19