# Pgfplots height in subfigure not consistent to adjacent includegraphics

I want to place 3 pictures next to each other using subcaption. The two right pictures are external graphics files that I include using \includegraphics. The left one is supposed to be a pgfplots chart. Naturally, I want them and the captions to align vertically. To achieve set I use a common height for all three pictures which is defined in \figheight. As a dry run, everything seems to work with example-image-a, etc:

However, when I replace the left figure by a pgfplot and specify its exact height to the height of the external figures right next, the result is somehow curious:

Why is the height not exactly the value of \figheight? Is there a difference between the height of the axis environment and the height of the tikzpicture? From the manual:

If scale only axis=false (the default), pgfplots will try to produce the desired width including labels, titles and ticks.

I guess the same holds for the height?! How can I fix this for a proper alignment of the pictures as well as the subcaptions?

## MWE

\documentclass{article}

\usepackage{graphicx}
\usepackage{pgfplots}
\usepackage{subcaption}

\newlength{\figheight}
\setlength{\figheight}{5cm}

\begin{document}

Works:

\begin{figure}[htbp]
\begin{subfigure}{0.65\linewidth}
\centering
\includegraphics[width=\linewidth,height=\figheight]{example-image-a}
\caption{Test1}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-b}
\caption{Test2}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-c}
\caption{Test3}
\end{subfigure}
\caption{Overall caption}
\end{figure}

Weird size and resulting caption position:

\begin{figure}[htbp]
\begin{subfigure}{0.65\linewidth}
\centering
\begin{tikzpicture}
\begin{axis}[
width=\linewidth,
height=\figheight,
]
\addlegendentry{$f(x)=x$}
\end{axis}
\end{tikzpicture}
\caption{Test1}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-b}
\caption{Test2}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-c}
\caption{Test3}
\end{subfigure}
\caption{Overall caption}
\end{figure}

\end{document}


The problem is that the axis environment will take into account, for the height, also the minimum size of the title and of the xlabel. See:

\documentclass{article}

\usepackage{graphicx}
\usepackage{pgfplots}
\usepackage{subcaption}

% modified from @egreg idea https://tex.stackexchange.com/a/88624/38080
\usepackage{xparse}
\newsavebox{\fminipagebox}
\NewDocumentEnvironment{fminipage}{O{c} O{} O{c} m O{\fboxsep}}
{\par\kern#5\noindent\begin{lrbox}{\fminipagebox}
\begin{minipage}[#1][#2][#3]{#4}\ignorespaces}
{\end{minipage}\end{lrbox}%
\makebox[#4]{%
\kern\dimexpr-\fboxsep-\fboxrule\relax
\fbox{\usebox{\fminipagebox}}%
\kern\dimexpr-\fboxsep-\fboxrule\relax
}\par\kern#5
}

\newlength{\figheight}
\setlength{\figheight}{5cm}

\begin{document}

\begin{figure}[htbp]
\begin{subfigure}{0.65\linewidth}
\centering
\setlength{\fboxsep}{0pt}
\begin{fminipage}[t][\figheight][t]{\linewidth}%
\begin{tikzpicture}
\begin{axis}[
height=\figheight,
width=\linewidth,
xlabel=$x$,
title = title,
]
\addlegendentry{$f(x)=x$}
\end{axis}
\end{tikzpicture}
\end{fminipage}
\caption{Test1 \the\linewidth \the\figheight}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-b}
\caption{Test2}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-c}
\caption{Test3}
\end{subfigure}
\caption{Overall caption}
\end{figure}

\end{document}


which gives (notice I added a "no size" frame around):

I do not know how to remove these sizes from the graph. Something on the line of

\begin{axis}[
height=\figheight+\baselineskip,
width=\linewidth,
xlabel = \empty,
title = \empty,
]


gives a better appearance:

but I feel this is a bit of an hack...

The best I can suggest is to add the external (zero size) frame and remove the graph one, like:

\setlength{\fboxsep}{0pt}
\begin{fminipage}[t][\figheight][t]{\linewidth}%
\centering
\begin{tikzpicture}
\begin{axis}[
height=\figheight+\baselineskip,
width=\linewidth,
xlabel = \empty,
title = \empty,
axis x line = center,
axis y line = center,
]
\addlegendentry{$f(x)=x$}
\end{axis}
\end{tikzpicture}
\end{fminipage}


which gives:

Not exactly aligned but fairly close:

\documentclass{article}
\usepackage{graphicx}
\usepackage{pgfplots}
\usepackage{subcaption}

\newlength{\figheight}
\setlength{\figheight}{5cm}

\begin{document}

Works:
\begin{figure}[htbp]
\begin{subfigure}{0.65\linewidth}
\centering
\includegraphics[width=\linewidth,height=\figheight]{example-image-a}
\caption{Test1}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-b}
\caption{Test2}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-c}
\caption{Test3}
\end{subfigure}
\caption{Overall caption}
\end{figure}

Weird size and resulting caption position:

\begin{figure}[htbp]
\begin{subfigure}{0.65\linewidth}
\centering
\begin{tikzpicture}
\begin{axis}[
%       width=\linewidth,
height=\figheight-\baselineskip, % changed
]
\addlegendentry{$f(x)=x$}
\end{axis}
\end{tikzpicture}
\caption{Test1}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-b}
\caption{Test2}
\end{subfigure}
\hfill
\begin{subfigure}{0.16\linewidth}
\centering
\includegraphics[angle=90,width=\linewidth,height=\figheight]{example-image-c}
\caption{Test3}
\end{subfigure}
\caption{Overall caption}
\end{figure}
\end{document}


Assuming you want to align the bounding box of the (whole) axis environment (and not only the "box" of the axis environment) you have to tweek the height a little bit. The PGFPlots manual states in section 4.10.1 at the height key:

[...]
Please note that pgfplots only estimates the size needed for axis and tick labels. The estimate assumes a fixed amount of space for anything which is outside of the axis box. This has the effect that the final images may be slightly larger or slightly smaller than the prescribed dimensions. However, the fixed amount is always the same; it is set to 45pt.
[...]

• ticklabels,
• axis labels, and
• title.

Thus, if some of them are missing, we have to "compensate" for that.

Please find attached some code how I would do it together with a lot of comments.

% used PGFPlots v1.15
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{
% use layers to show the bounding boxes of the axis' environments
set layers={
background,
main,
},
}
\newlength{\figheight}
\setlength{\figheight}{5cm}
\begin{document}
% by default the width' and height' are reduced by 45pt which is used
% for ticklabels, axis labels and the title
\begin{tikzpicture}
\begin{axis}[
width=\figheight,
height=\figheight,
xlabel=$x$,
ylabel=$y$,
title=title,
name=p,
]
\end{axis}

\begin{pgfonlayer}{background}
\fill [yellow!10] (p.outer south west)
rectangle (p.outer north east);
\end{pgfonlayer}

\draw [red] (p.outer south east)
-- +(0,\figheight) circle (1.5pt);
\draw [red] (p.outer south east)
-- +(-\figheight,0) circle (1.5pt);
\end{tikzpicture}
%
\includegraphics[angle=90,height=\figheight]{example-image-a}
%
% so if no title and y label are given and we want to align the bounding
% box of the whole axis' environment (not only the box of the axis'
% environment) with the bounding box of the graphics, we have to enlarge
% the height' (manually) to fit to the desired height'.
\begin{tikzpicture}
\begin{axis}[
width=\figheight,
% -----------------------------------------------------------------
height=\figheight + 30pt,
%            % -------------------------
%            % equivalently we have to reduce the height' if scale only axis'
%            % is given
%            scale only axis,
%            height=\figheight - 15pt,
% -----------------------------------------------------------------
name=q,
]
`