0

I am trying to make a figure with subfigures containing plots made with asymptotic functions and pgfplots. As one may see, the sizes of subfigures are different. I wish to make all the subfigures of the same size and also to make them align vertically and horizontally with each other.

Aligning them would mean, the y labels of plot 2 and plot 4 to come in line. The x labels of plot 1 and plot 2 are to come in line.

enter image description here

Updated code:

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

  • I think you are looking for the groupplot option. You can find it in the PGF manual. – DraUX Aug 15 '23 at 17:31
  • @DraUX Can you show this on my MWE using this for the asymptotic plot – Formal_this Aug 18 '23 at 15:45
  • 1
    You can find the syntax on page 456 on the pgfplots manual. Maybe you try it first yourself and add the code as far as you come. Then I can try to help you finishing it. The manual also gives some examples how to use the option. Be aware that you have to put \usepgfplotslibrary{groupplots} in your preamble – DraUX Aug 18 '23 at 16:58
  • @DraUX Sure, I am trying to incorporate this. But the example has 1 \begin{tikzpicture} but I am currently having 4; also how to place the \begin{loglogaxis}[] ... inside the grouplot ? – Formal_this Aug 18 '23 at 17:10

1 Answers1

2

First a few things about your question. When I first opened it, it didn't compile. Please make sure to always post a question that compiles so the people helping you can focus on actually solve the problem you have rather than building the problem you have. Furthermore try to shrink down your code to the absolute minimum necessary (minimal working example) so it is clear where your problem is located.

Now to your problem: As it is said in the pgfplots manual (p.456) groupplot can be considered an extension of the axis environment. So the following code

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

converts to

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

Considering this you can try something like

\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(170x)cos(100x)/(x^2+1)}; \addlegendentry{$F(x)=\dfrac{\cos(100x)}{x^2+1}J_0(170x)$} \addplot[black, samples = 5000] gnuplot {besj0(90x)cos(100x)/(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(100cosh(\x) r)}); \addplot[orange,samples=1000,domain=1.5:2]plot (\x, {exp(\x)sin(100cosh(\x) r)}); \addplot[black,samples=500,domain=0:1.5]plot (\x, {exp(\x)sin(10cosh(\x) r)}); \addplot[black,samples=1000,domain=1.5:2]plot (\x, {exp(\x)sin(10cosh(\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}

what gives you enter image description here

Some more things I changed:

  • converted your plot in asymptote to pgfplots using gnuplot since I couldn't find a solution of asymptote and groupplot working together
  • changed the sample number of the Bessel-Plots to 5000, since they didn't look clear (you probably have to adjust it further
  • fixed your legend of the last plot since it was showing two orange lines for the plots before
  • added x axis limits for plot 4
  • deleted all for the problem unnecessary packages and options as well as all the commented code

Edit:

  • I have no problems to compile the document with XeLaTeX. I tried it in Overleaf and changed the compiler to XeLaTeX which had no problems at all. Probably there is an error in the other parts of your document?
  • the alignment of the ylabels is orientated at the width of the yticks. Since they are of different size in the two plots on the right, the labes are at different location. You can correct that by manually setting the position of the labels. just add something like y label style={at={(-0.15,0.5)}},. The coordinates are relative coordinates to the size of the plot-scale. E.g. this means at 50% of the height and at -15% of the width. All four plots are of the same width and height (because this values are set in the global options for all the plots: \begin{groupplot}[..., height=0.35\textheight, width=0.48\textwidth]) so the identical relative placement of the ylabel results in an vertical and horizontal alignment.
  • regarding the subcaptions I guess you are refering to an answer on this question. You may notice, that at this question the groupplot environment was given the name my plots so you can address it. If you add a corresponding name like \begin{groupplot}[group style={group name=my plots,...},...] the command works just fine. However I tried a different approach since the subcaption was overlapping with the xlabel of the plots. Instead I named the x labels of all the plots by adding xlabel style = {name = label_plot_x},. Now you can position the subcaption relative to that. E.g. by adding the following code
\node[text width=0.48\textwidth, align=left, anchor=north] at (label_plot_x.south) {\subcaption{Caption of plot x \label{subplot:plot_x}}};
  • Be aware that the width of the plots and of the subcaption-nodes should match (I changed that value to 0.45\textwidth in comparison with my first answer)
  • I changed the style of the yticks of the upper right plot to match the style in your question by adding the following code.
yticklabel style={
    /pgf/number format/fixed,
    /pgf/number format/precision=2,
},
scaled y ticks = false,
  • I moved the legend of the upper right plot to the top since it was overlapping with the plot and I made the box a little bit bigger so all of the legend fits in it. This was done by adding
legend style = {
    at={(0.5,1.05)},
    anchor=south,
    minimum height=1.2cm,
},

So the final code looks like that

\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(170x)cos(100x)/(x^2+1)}; \addlegendentry{$F(x)=\dfrac{\cos(100x)}{x^2+1}J_0(170x)$} \addplot[black, samples = 5000] gnuplot {besj0(90x)cos(100x)/(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(100cosh(\x) r)}); \addplot[orange,samples=1000,domain=1.5:2]plot (\x, {exp(\x)sin(100cosh(\x) r)}); \addplot[black,samples=500,domain=0:1.5]plot (\x, {exp(\x)sin(10cosh(\x) r)}); \addplot[black,samples=1000,domain=1.5:2]plot (\x, {exp(\x)sin(10cosh(\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}

That compiles to the following enter image description here

DraUX
  • 483
  • Thanks for the help and a step-by-step buildup to the solution. – Formal_this Aug 18 '23 at 20:19
  • One more observation, the y_label of top_right and bottom_right seem to not align along the vertical line. Also they are a bit far away from their respective y-axes. – Formal_this Aug 18 '23 at 20:58
  • I was able to correct the above alignment issue. However, I was not able to get sub-captions beneath each of the four subfigures as in the initial MWE. – Formal_this Aug 19 '23 at 01:26
  • I tried adding \node[text width=6cm,align=center,anchor=north] at ([yshift=-5mm] my_plots c1r1.south){sub caption}; but that doesn't work. – Formal_this Aug 19 '23 at 02:18
  • I am using Overleaf and my main.tex file compiles in XeLaTeX; how to compile this figure file in my main.tex as this figure compiles in pdfLaTeX. – Formal_this Aug 19 '23 at 02:24
  • I edited my answer and addressed the other things you were mentioning – DraUX Aug 19 '23 at 11:05