子图中的 Pgfplots 高度与相邻的包含图形不一致

子图中的 Pgfplots 高度与相邻的包含图形不一致

我想使用以下方法将 3 张图片并排放置subcaption。右边两张图片是我使用的外部图形文件\includegraphics。左边的应该是pgfplots图表。当然,我希望它们和标题垂直对齐。为了实现设置,我为所有三张图片使用了在中定义的共同高度\figheight。作为试运行,一切似乎都正常工作示例图像-a, ETC:

在此处输入图片描述

然而,当我用 pgfplot 替换左边的图并将其精确地指定height为接下来的外部图的高度时,结果有些奇怪:

在此处输入图片描述

为什么高度不完全是 的值\figheight? axis 环境的高度和 tikzpicture 的高度有区别吗? 来自手册:

如果 scale only axis=false (默认值),pgfplots 将尝试生成所需的宽度,包括标签、标题和刻度。

我猜高度也是一样?!我该如何修复这个问题,才能正确对齐图片和子标题?


平均能量损失

\documentclass{article}

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

\pgfplotsset{compat=newest}

\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,
      ]
        \addplot+ {x};
        \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}

答案1

问题是,axis对于 ,环境还会考虑height标题和 的最小大小xlabel。请参阅:

\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
 }

\pgfplotsset{compat=newest}

\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,
      ]
        \addplot+ {x};
        \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}

结果是(注意我添加了一个“无尺寸”框):

完美对齐的事物……

我不知道如何从图表中删除这些尺寸。

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

看起来更美观:

尝试一个

但我觉得这有点像黑客行为......

我能建议的最好方法是添加外部(零尺寸)框架并删除图形框架,例如:

\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,
        ]
        \addplot+ {x};
        \addlegendentry{$f(x)=x$}
      \end{axis}
    \end{tikzpicture}
\end{fminipage}

这使:

第二次尝试

答案2

不完全一致但相当接近:

在此处输入图片描述

\documentclass{article}
\usepackage{graphicx}
\usepackage{pgfplots}
\usepackage{subcaption}
\pgfplotsset{compat=newest}

\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
        scale only axis                  % added
      ]
        \addplot+ {x};
        \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}

答案3

假设你想对齐边界框整个axis环境(而不仅仅是axis环境的“盒子”),你必须稍微调整height一下。PGFlots 手册第 4.10.1 节中的height关键规定如下:

[...]
请注意,pgfplots 仅估计轴和刻度标签所需的大小。估计假设轴框外的任何内容都有固定的空间量。这会导致最终图像可能比规定的尺寸略大或略小。但是,固定量始终相同;它设置为 45pt。
[...]

正如 Rmano 已经指出的那样他的回答这大约是

  • 勾选标签,
  • 轴标签,以及
  • 标题。

因此,如果其中一些缺失,我们必须“补偿”。

请参阅附件中我将如何执行的一些代码以及大量注释。

% 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,
        ]
            \addplot {x};
        \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,
        ]
            \addplot {x};
        \end{axis}

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

        \draw [red] (q.outer south west)
            -- +(0,\figheight) circle (1.5pt);
        \fill [green] (q.outer north west) circle (1pt);
    \end{tikzpicture}
\end{document}

该图显示了上述代码的结果

相关内容