1

In this MWE, how can I make tikzpicture fit the allocated space of parent float environment (figure or subfigure)?

\RequirePackage{luatex85}
\documentclass{article}
\usepackage{pgfplots,caption,subcaption,mwe}

\pgfplotsset{compat=newest}

\begin{document}

\begin{figure}
    \begin{subfigure}[t]{0.3\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-a};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}
    %
    \begin{subfigure}[t]{0.3\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-b};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}
    %
    \begin{subfigure}[t]{0.3\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-c};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}
\end{figure}

\end{document}

enter image description here


Edit

The output of code below doesn't make subfigures span over all \textwidth despite making each subfigure width equal to 0.33\textwidth.

\begin{figure}
    \centering
    \begin{subfigure}[t]{0.33\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\textwidth]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-a};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}
    %
    \begin{subfigure}[t]{0.33\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\textwidth]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-b};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}
    %
    \begin{subfigure}[t]{0.33\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\textwidth]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-c};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}
\end{figure}

\lipsum[1]

enter image description here

Diaa
  • 9,599
  • Add width=\textwidth to the axis options? Or is that insufficient? – Torbjørn T. Jan 23 '17 at 15:50
  • @TorbjørnT. Thanks for your comment, regarding my edit, there is a gap between the subfigures I don't know how to control it; additionally, the tikzpicture doesn't seem to fit well the subfigure width. – Diaa Jan 23 '17 at 16:15
  • Well, there is a space between each of the subfigures, add % after the first two \end{subfigure}s. And yes, the width setting of pgfplots is only approximate, as it doesn't actually measure the width of the ticklabels/axis labels. You could \resizebox it, though that isn't ideal. – Torbjørn T. Jan 23 '17 at 16:42
  • @TorbjørnT. Apart from subfigure approach, I would be grateful if you could provide me any answer that makes these ikzpictures span the whole textwidth with control over the spacing between them. – Diaa Jan 23 '17 at 17:07

1 Answers1

1

The reason you get the third subfigure on a separate line is that you have a space between the subfigures. A linebreak in the code is the same as a space, so you need a % after \end{subfigure}. I.e., instead of

\end{subfigure}
%
\begin..

you need

\end{subfigure}%
%
\begin..

or

\end{subfigure}%
\begin..

See e.g. What is the use of percent signs (%) at the end of lines?

The second problem is that the width key for a pgfplots axis isn't actually accurate. What pgfplots does is to assume that the ticklabels and axis labels take up an 45pt of space outside the axis itself. So it takes the specified width, subtracts 45pt, and uses this width for the axis.

You can't change the 45pt to something else, but you can calculate your own axis width, and use the scale only axis key to say that the width parameter applies to the axis disregarding ticklabels/axis labels.

A cruder method is to put the whole tikzpicture in a \resizebox, and simply scale it up to the width of the subfigure. The problem of this is that fonts are resized as well.

Last, note that if you don't have captions for these, then the subfigure environments are somewhat pointless, and can be discarded.

The first row shows the effect of \resizebox, in the second I used a calculated width for the axes, and in the third the same, but without subfigure environments. The showframe package prints a frame around the text area, those are the lines seen in the screenshot:

enter image description here

\RequirePackage{luatex85}
\documentclass{article}
\usepackage{pgfplots,subcaption,showframe}

\pgfplotsset{compat=newest}

\begin{document}
\begin{figure}
    \centering
    \begin{subfigure}[t]{0.33\textwidth}
        \resizebox{\textwidth}{!}{\begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\textwidth]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-a};
            \end{axis}
        \end{tikzpicture}}
    \end{subfigure}%
    %
    \begin{subfigure}[t]{0.33\textwidth}
        \resizebox{\textwidth}{!}{\begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\textwidth]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-b};
            \end{axis}
        \end{tikzpicture}}
    \end{subfigure}%
    %
    \begin{subfigure}[t]{0.33\textwidth}
        \resizebox{\textwidth}{!}{\begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\textwidth]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-c};
            \end{axis}
        \end{tikzpicture}}
    \end{subfigure}

    \pgfmathsetlengthmacro{\myaxiswidth}{0.33\textwidth-width(" 150 ")}% subtract width of widest ticklabel, with a space on each side
    \begin{subfigure}[t]{0.33\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\myaxiswidth,scale only axis]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-a};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}%
    %
    \begin{subfigure}[t]{0.33\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\myaxiswidth,scale only axis]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-b};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}%
    %
    \begin{subfigure}[t]{0.33\textwidth}
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\myaxiswidth,scale only axis]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-c};
            \end{axis}
        \end{tikzpicture}
    \end{subfigure}


        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\myaxiswidth,scale only axis]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-a};
            \end{axis}
        \end{tikzpicture}%
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\myaxiswidth,scale only axis]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-b};
            \end{axis}
        \end{tikzpicture}%
        \begin{tikzpicture}
            \begin{axis}[enlargelimits=false,width=\myaxiswidth,scale only axis]
                \addplot graphics [
                    xmin=0,
                    xmax=50,
                    ymin=0,
                    ymax=150,
                ] {example-image-c};
            \end{axis}
        \end{tikzpicture}

\end{figure}

\end{document}
Torbjørn T.
  • 206,688
  • I really appreciate your informative answer. I am so sorry, but I have a naive question: what is the meaning of width(" 150 ")? I changed this number, and I found it affects the size of tikzpicture inside the subfigure. However, I don't know what its unit is and why it is enclosed by double quotes. Additionally, was 150 calculated or set by trial and error? – Diaa Jan 23 '17 at 17:19
  • 1
    @DiaaAbidou " 150 " is not a number, it's a string. Chosen because the widest yticklabel is 150. The pgf math function width("...") calculates the width of .... Instead of width(" 150 ") you could write say 15pt, and vary 15pt till you found a reasonable value. – Torbjørn T. Jan 23 '17 at 17:36
  • 1
    And no need to be so sorry for that, it's an honest question. – Torbjørn T. Jan 23 '17 at 17:37