如何使用 pgfplots 和渐近图调整子图?

如何使用 pgfplots 和渐近图调整子图?

我正在尝试制作一个包含使用渐近函数和 pgfplots 绘制的图的子图。正如人们所看到的,子图的大小不同。我希望使所有子图的大小相同,并使它们垂直和水平对齐。

对齐它们意味着绘图 2 和绘图 4 的 y 标签要对齐。绘图 1 和绘图 2 的 x 标签要对齐。

在此处输入图片描述

更新的代码:

\documentclass[12pt, a4paper,
                parskip=half,
                toc=bibliography,
                numbers=noendperiod
               ]{scrbook}

\usepackage[hmargin={3.0cm, 2.5cm},
            vmargin={2.5cm, 2.0cm},
            includehead,    includefoot
            ]{geometry}

\usepackage[UKenglish]{babel}
\usepackage[T1]{fontenc}

\usepackage{scrlayer-scrpage}
\usepackage{subcaption}
\usepackage{caption}
%\addtokomafont{caption}{\scriptsize}
\setkomafont{captionlabel}{\bfseries\rmfamily}
%\addtokomafont{caption}{\scriptsize}

\usepackage[dvipsnames,table,xcdraw]{xcolor}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

\usepackage[inline]{asymptote}
%import graph; 
%\usepackage[paper=a4paper,hmargin=2cm,vmargin=2.5cm]{geometry}
%\usepackage{parskip}
%\setlength{\columnsep}{3em}

%\title{Asymptote 3D graphics}


\begin{document}
    \begin{figure}[ht]
            \pgfplotsset{
                     width=\linewidth, height=0.9\linewidth,
                     %enlarge y limits=0.1,
                     %tick label style={font=\scriptsize},
                     %xticklabel style = {text width=0.4em},
                     %ylabel style = {text width=1em, inner sep=2pt},
                     %yticklabel style = {text width=0.2em},
                     label style={font=\bfseries\boldmath},
                     %tick label style={font=\bfseries\boldmath},
                     %
                     %tick align = outside,
                     %tick pos = left,
                     %every axis plot post/.append style={color=Blue, dashed, mark=*}, 
                     }
                \begin{subfigure}[t]{0.48\linewidth}
                        \begin{tikzpicture}
                            \begin{loglogaxis}[
                            xmin=0.1, xmax=0.1e8,
                            ymin=1e-8, ymax=5e3,
                            xlabel={Number of Flops}, 
                            ylabel={Normalized MSE: $\log_{10} (e)$ },
                            scatter/classes={ a={mark=square*, blue}, b={mark=square*, red}, c={mark=square, black}, d={mark=triangle*, blue}, e={mark=triangle*, red},f={mark=triangle*, black},g={mark=x, black}, h={mark= diamond*, pink} },
                            ] 
                                \addplot[scatter, only marks,
                                scatter src=explicit symbolic]
                                table[meta=label] {
                                    x     y      label
                                    144 0.11587881 a
                                    };

                            \end{loglogaxis}
                        \end{tikzpicture}
                    \caption{Plot 1}
                \end{subfigure}
            \hfill
                \begin{subfigure}[t]{0.48\linewidth}
                    %\begin{tikzpicture}
                        %\begin{axis}[
                        %    %domain=0:25,
                        %    ymin= -3e-2, ymax= 3e-2,
                        %    xmin=1, xmax=2,
                        %    xlabel={Input $x$},
                        %    ylabel={$f(x)$} ]
                            \begin{asy}
                                    import graph; 
                                    size(7.5cm,8cm,IgnoreAspect);
                                    real xmin=1,xmax=2, ymin=-.03,ymax=.03;
                                    pair f(real x){return (x,Jn(0,170x)*cos(100x)/(x^2+1));}
                                    guide gf=graph(f,xmin,xmax,n=1000);
                                    (draw(gf,orange));
                                    pair f(real x){return (x,Jn(0,90x)*cos(100x)/(x^2+1));}
                                    guide gf2=graph(f,xmin,xmax,n=1000);
                                    (draw(gf2,black));
                                    label("$F(x)=\dfrac{\cos(100x)}{x^2+1}J_0(170x)$",(2,.02),2W); xaxis("Input",BottomTop,LeftTicks); yaxis("$f(x)$",LeftRight,RightTicks);

                            \end{asy}
                            
                        %\end{axis}       
                    %\end{tikzpicture}
                    \caption{Plot 2}
                \end{subfigure}
        
            \medskip
                \begin{subfigure}[t]{0.48\linewidth}
                    \begin{tikzpicture}
                        \begin{loglogaxis}[
                        xmin=0.1, xmax=0.1e8,
                        ymin=1e-7, ymax=5e3,
                        xlabel={Number of Flops}, 
                        ylabel={Normalized MSE: $\log_{10} (e)$ },
                        %label style={font=\bfseries\boldmath},
                        %tick label style={font=\bfseries\boldmath},
                        scatter/classes={ a={mark=square*, blue}, b={mark=square*, red}, c={mark=square, black}, d={mark=triangle*, blue}, e={mark=triangle*, red},f={mark=triangle*, black},g={mark=x, black}, h={mark= diamond*, pink} },
                        ] 
                            \addplot[scatter, only marks,
                            scatter src=explicit symbolic]
                                table[meta=label] {
                                    x     y      label
                                    320 0.608216725 a
\
                                    };

                        \end{loglogaxis}
                    \end{tikzpicture}
                    \caption{Plot 3}
                \end{subfigure}
            \hfill
                \begin{subfigure}[t]{0.48\linewidth}
                    %\begin{tikzpicture}
                    %    \begin{axis}[
                    %        domain=0:1,
                    %        xlabel={Input $x$}, 
                    %        ylabel={$f(x)$},
                    %        ymin= 0, ymax=1e1,
                    %                ]
                    %        \addplot  {e^x)};
                    %        \addplot  {e^(2*x))};
                    %        \legend{$\exp(x)$,$\exp(2x)$}
                    %    \end{axis}
                    %\end{tikzpicture}
                    \begin{tikzpicture}
                        \begin{axis}[%domain=0:1,
                            xlabel={Input $x$}, 
                            ylabel={$f(x)$},
                            ymin= -1e1, ymax=1e1 ]
                            \addplot[orange,samples=500,domain=0:1.5]plot (\x, {exp(\x)*sin(100*cosh(\x) r)});
                            \addplot[orange,samples=1000,domain=1.5:2]plot (\x, {exp(\x)*sin(100*cosh(\x) r)});
                            %\legend{\textcolor{orange}{$\mathrm e^x\sin\left(100\cosh\left(x\right)\right)$}}
                            
                            \addplot[black,samples=500,domain=0:1.5]plot (\x, {exp(\x)*sin(10*cosh(\x) r)});
                            \addplot[black,samples=1000,domain=1.5:2]plot (\x, {exp(\x)*sin(10*cosh(\x) r)});
                            
                            \legend{\textcolor{black}{$\mathrm e^x\sin\left(100\cosh\left(x\right)\right)$}, \textcolor{black}{$\mathrm e^x\sin\left(10\cosh\left(x\right)\right)$}}
                            
                        \end{axis}
                    \end{tikzpicture}
                    \caption{Plot 4}
                \end{subfigure}
        \caption{caption for all plots}
        \label{all_plots}
    \end{figure}
\end{document}

答案1

首先说几句关于你问题的事情。我第一次打开它时,它没有编译。请确保始终发布一个可以编译的问题,这样帮助你的人就可以专注于真正解决你遇到的问题,而不是构建你遇到的问题。此外,尝试将代码缩减到绝对必要的最小值(最小工作示例),这样你的问题就一目了然了。

现在来谈谈你的问题:正如pgfplots 手册(p.456)groupplot可以被认为是环境的扩展axis。因此,以下代码

\begin{tikzpicture}
  \begin{axis}[put your options for pic 1 here]
    //your plots 1
  \end{axis}
\end{tikzpicture}

\begin{tikzpicture}
  \begin{axis}[put your options for pic 2 here]
    //your plots 2
  \end{axis}
\end{tikzpicture}

转换为

\begin{tikzpicture}
  \begin{groupplot}[put your groupplot options here]
    \nextgroupplot[put your options for pic 1 here]
      \\your plots 1
    \nextgroupplot[put your options for pic 2 here]
      \\your plots 2
  \end{axis}
\end{tikzpicture}

考虑到这一点,你可以尝试类似

\documentclass{scrbook}
\usepackage{amsmath}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.18}

\begin{document}
\begin{figure}[ht]
\pgfplotsset{label style={font=\bfseries\boldmath}}
    \begin{tikzpicture}
        \begin{groupplot}[group style={group size=2 by 2, vertical sep=1.5cm, horizontal sep = 1.8cm}, height=0.35\textheight, width=0.48\textwidth]
            \nextgroupplot[
                ymode=log,
                xmode = log,
                xmin=0.1, xmax=0.1e8,
                ymin=1e-8, ymax=5e3,
                xlabel={Number of Flops}, 
                ylabel={Normalized MSE: $\log_{10} (e)$ },
                scatter/classes={ a={mark=square*, blue}, b={mark=square*, red}, c={mark=square, black}, d={mark=triangle*, blue}, e={mark=triangle*, red},f={mark=triangle*, black},g={mark=x, black}, h={mark= diamond*, pink} },
            ] 
            \addplot[scatter, only marks, scatter src=explicit symbolic]
                table[meta=label] {
                    x     y      label
                    144 0.11587881 a
                };
            \nextgroupplot[
                xmin = 1, xmax = 2,
                ymin = -0.03, ymax = 0.03,
                xlabel = {Input},
                ylabel = {$f(x)$},
            ]
            \addplot[orange, samples = 5000] gnuplot {besj0(170*x)*cos(100*x)/(x^2+1)};
            \addlegendentry{$F(x)=\dfrac{\cos(100x)}{x^2+1}J_0(170x)$}
            \addplot[black, samples = 5000] gnuplot {besj0(90*x)*cos(100*x)/(x^2+1)};
            \nextgroupplot[
                ymode=log,
                xmode=log,
                xmin=0.1, xmax=0.1e8,
                ymin=1e-7, ymax=5e3,
                xlabel={Number of Flops}, 
                ylabel={Normalized MSE: $\log_{10} (e)$ },
                scatter/classes={ a={mark=square*, blue}, b={mark=square*, red}, c={mark=square, black}, d={mark=triangle*, blue}, e={mark=triangle*, red},f={mark=triangle*, black},g={mark=x, black}, h={mark= diamond*, pink} }]
            \addplot[scatter, only marks, scatter src=explicit symbolic]
                table[meta=label] {
                    x     y      label
                    320 0.608216725 a
                };
            \nextgroupplot[
                xlabel={Input $x$}, 
                ylabel={$f(x)$},
                xmin = 0, xmax = 2,
                ymin= -1e1, ymax=1e1
            ]
            \addlegendimage{orange}
            \addlegendimage{black}
            \legend{\textcolor{black}{$\mathrm e^x\sin\left(100\cosh\left(x\right)\right)$}, \textcolor{black}{$\mathrm e^x\sin\left(10\cosh\left(x\right)\right)$}}
            \addplot[orange,samples=500,domain=0:1.5]plot (\x, {exp(\x)*sin(100*cosh(\x) r)});
            \addplot[orange,samples=1000,domain=1.5:2]plot (\x, {exp(\x)*sin(100*cosh(\x) r)});
            \addplot[black,samples=500,domain=0:1.5]plot (\x, {exp(\x)*sin(10*cosh(\x) r)});
            \addplot[black,samples=1000,domain=1.5:2]plot (\x, {exp(\x)*sin(10*cosh(\x) r)});
            \end{groupplot}
        \end{tikzpicture}
    \caption{caption for all plots; \textbf{top left:} text; \textbf{top right:} more text; \textbf{bottom left:} still more text; \textbf{bottom right:} last text}
    \label{all_plots}
\end{figure}
\end{document}

是什么让你 在此处输入图片描述

我还做了一些改变:

  • 将您的情节转换asymptotepgfplots使用gnuplot,因为我找不到解决方案asymptotegroupplot一起工作
  • 将贝塞尔图的样本数量改为 5000,因为它们看起来不太清晰(你可能需要进一步调整
  • 修复了上一个图例,因为之前的图例显示了两条橙色的线
  • 为图 4 添加了 x 轴限制
  • 删除了问题中所有不必要的包和选项以及所有注释的代码

编辑:

  • 使用 XeLaTeX 编译文档没有任何问题。我在 Overleaf 中尝试过,并将编译器更改为 XeLaTeX,完全没有问题。您的文档的其他部分可能有错误?
  • 的对齐方式ylabels以 的宽度为导向yticks。由于右侧两个图中的尺寸不同,因此标签位于不同的位置。您可以通过手动设置标签的位置来更正此问题。只需添加类似 的内容即可y label style={at={(-0.15,0.5)}},。坐标是相对于绘图比例大小的相对坐标。例如,这意味着高度为 50%,宽度为 -15%。所有四个绘图的宽度和高度均相同(因为这些值是在所有绘图的全局选项中设置的: ),因此在垂直和水平对齐中导致\begin{groupplot}[..., height=0.35\textheight, width=0.48\textwidth]相同的相对位置。ylabel
  • 关于副标题,我猜你指的是这个问题。您可能会注意到,在这个问题中,groupplot环境被赋予了名称my plots,以便您可以解决它。如果您添加相应的名称,例如\begin{groupplot}[group style={group name=my plots,...},...]命令工作正常。但是我尝试了一种不同的方法,因为子标题与图的重叠xlabel。相反,我通过添加来命名所有图的 x 标签xlabel style = {name = label_plot_x},。现在您可以相对于它定位子标题。例如,通过添加以下代码
\node[text width=0.48\textwidth, align=left, anchor=north] at (label_plot_x.south) {\subcaption{Caption of plot x \label{subplot:plot_x}}};
  • 请注意,图表和子标题节点的宽度应该匹配(我将该值更改为0.45\textwidth与我的第一个答案相比)
  • 我通过添加以下代码将右上角图表的样式更改yticks为与您问题中的样式相匹配。
yticklabel style={
    /pgf/number format/fixed,
    /pgf/number format/precision=2,
},
scaled y ticks = false,
  • 我将右上角图例移到了顶部,因为它与图例重叠,并且我将框稍微放大一点,以便所有图例都适合它。这是通过添加
legend style = {
    at={(0.5,1.05)},
    anchor=south,
    minimum height=1.2cm,
},

所以最终的代码是这样的

\documentclass{scrbook}
\usepackage{amsmath}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.18}
\usepackage{caption, subcaption}

\begin{document}
\begin{figure}[ht]
\pgfplotsset{label style={font=\bfseries\boldmath}}
    \begin{tikzpicture}
        \begin{groupplot}[group style={group name=my plots, group size=2 by 2, vertical sep=2.5cm, horizontal sep =1.8cm}, height=0.32\textheight, width=0.45\textwidth]
            \nextgroupplot[
                ymode=log,
                xmode = log,
                xmin=0.1, xmax=0.1e8,
                ymin=1e-8, ymax=5e3,
                xlabel={Number of Flops}, 
                xlabel style = {name = label_upper_left},
                ylabel={Normalized MSE: $\log_{10} (e)$ },
                scatter/classes={ a={mark=square*, blue}, b={mark=square*, red}, c={mark=square, black}, d={mark=triangle*, blue}, e={mark=triangle*, red},f={mark=triangle*, black},g={mark=x, black}, h={mark= diamond*, pink} },
            ] 
            \addplot[scatter, only marks, scatter src=explicit symbolic]
                table[meta=label] {
                    x     y      label
                    144 0.11587881 a
                };
            \nextgroupplot[
                xmin = 1, xmax = 2,
                ymin = -0.03, ymax = 0.03,
                xlabel = {Input},
                ylabel = {$f(x)$},
                y label style={at={(-0.15,0.5)}},
                xlabel style = {name = label_upper_right},
                yticklabel style={
                    /pgf/number format/fixed,
                    /pgf/number format/precision=2,
                },
                scaled y ticks = false,
                legend style = {
                    at={(0.5,1.05)},
                    anchor=south,
                    minimum height=1.2cm,
                },
            ]
            \addplot[orange, samples = 5000] gnuplot {besj0(170*x)*cos(100*x)/(x^2+1)};
            \addlegendentry{$F(x)=\dfrac{\cos(100x)}{x^2+1}J_0(170x)$}
            \addplot[black, samples = 5000] gnuplot {besj0(90*x)*cos(100*x)/(x^2+1)};
            \nextgroupplot[
                ymode=log,
                xmode=log,
                xmin=0.1, xmax=0.1e8,
                ymin=1e-7, ymax=5e3,
                xlabel={Number of Flops},
                xlabel style = {name = label_lower_left},
                ylabel={Normalized MSE: $\log_{10} (e)$ },
                scatter/classes={ a={mark=square*, blue}, b={mark=square*, red}, c={mark=square, black}, d={mark=triangle*, blue}, e={mark=triangle*, red},f={mark=triangle*, black},g={mark=x, black}, h={mark= diamond*, pink} }]
            \addplot[scatter, only marks, scatter src=explicit symbolic]
                table[meta=label] {
                    x     y      label
                    320 0.608216725 a
                };
            \nextgroupplot[
                xlabel={Input $x$}, 
                xlabel style = {name = label_lower_right},
                ylabel={$f(x)$},
                xmin = 0, xmax = 2,
                ymin= -1e1, ymax=1e1,
                y label style={at={(-0.15,0.5)}},
            ]
            \addlegendimage{orange}
            \addlegendimage{black}
            \legend{\textcolor{black}{$\mathrm e^x\sin\left(100\cosh\left(x\right)\right)$}, \textcolor{black}{$\mathrm e^x\sin\left(10\cosh\left(x\right)\right)$}}
            \addplot[orange,samples=500,domain=0:1.5]plot (\x, {exp(\x)*sin(100*cosh(\x) r)});
            \addplot[orange,samples=1000,domain=1.5:2]plot (\x, {exp(\x)*sin(100*cosh(\x) r)});
            \addplot[black,samples=500,domain=0:1.5]plot (\x, {exp(\x)*sin(10*cosh(\x) r)});
            \addplot[black,samples=1000,domain=1.5:2]plot (\x, {exp(\x)*sin(10*cosh(\x) r)});
        \end{groupplot}
        \node[text width=0.48\textwidth, align=center, anchor=north] at (label_upper_left.south) {\subcaption{Caption of upper left plot \label{subplot:upper_left}}};
        \node[text width=0.48\textwidth, align=center, anchor=north] at (label_upper_right.south) {\subcaption{Caption of upper right plot \label{subplot:upper_right}}};
        \node[text width=0.48\textwidth, align=center, anchor=north] at (label_lower_left.south) {\subcaption{Caption of lower left plot \label{subplot:lower_left}}};
        \node[text width=0.48\textwidth, align=center, anchor=north] at (label_lower_right.south) {\subcaption{Caption of lower right plot \label{subplot:lower_right}}};
    \end{tikzpicture}
    \caption{Caption for all plots}
    \label{all_plots}
\end{figure}
\end{document}

编译结果如下 在此处输入图片描述

相关内容