2

I am trying to produce a pdf with specific dimensions (221ptx150pt) overlaying two designs, one uses addplot with fill between and the other is a top down view of an addplot3. I want the addplot3 to extend the entire size of the image with the addplot extending the entire width and a fraction of the height that I can control.

If I only use addplot without fill between, the resulting .pdf is 184ptx125pt. The MWE and resulting image are shown here:

% !TEX TS-program = lualatex

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}

\usepgfplotslibrary{fillbetween}

\pgfmathdeclarefunction{wave}{3}{\pgfmathparse{#1*exp(-x*x/#2)*sin(2*pi*x/#3)}}

\pgfplotsset{compat=1.16,
             scale only axis = true,
             trig format=rad,
}

\begin{document}
\begin{tikzpicture}

\begin{axis}[
    hide axis,
    width=221 pt,
    height=150 pt,
]

\addplot[
  red,
  domain=-15:15,
  samples=100,
]
{wave(1.0,30,12.0)};

\addplot[
  red,
  domain=-15:15,
  samples=100,
]
{-0.2*wave(1.0,30,12.0)};

\end{axis}
\end{tikzpicture}
\end{document}

The function without a fill

If I add the fill between, the resulting .pdf is 221ptx150pt (or really close) as expected. However, the curve does not reach the edge of the .pdf in either x or y. The MWE and resulting image are shown here:

% !TEX TS-program = lualatex

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}

\usepgfplotslibrary{fillbetween}

\pgfmathdeclarefunction{wave}{3}{\pgfmathparse{#1*exp(-x*x/#2)*sin(2*pi*x/#3)}}

\pgfplotsset{compat=1.16,
             scale only axis = true,
             trig format=rad,
}

\begin{document}
\begin{tikzpicture}

\begin{axis}[
    hide axis,
    width=221 pt,
    height=150 pt,
]

\addplot[
  red,
  name path=A,
  domain=-15:15,
  samples=100,
]
{wave(1.0,30,12.0)};

\addplot[
  red,
  name path=B,
  domain=-15:15,
  samples=100,
]
{-0.2*wave(1.0,30,12.0)};

\addplot[
  fill=red,
]
fill between[
  of=A and B,
];

\end{axis}
\end{tikzpicture}
\end{document}

The function with a fill

If I add the top down 3D plot, the result changes further. The resulting .pdf is still 221px150pt, and the 3D plot extends the full width, but only a fraction of the height. Additionally, the original curve extends the full width but only a fraction of the height of the 3D plot. The MWE and resulting image are shown here:

% !TEX TS-program = lualatex

\documentclass{standalone}
\usepackage[cmyk]{xcolor}
\usepackage{tikz}
\usepackage{pgfplots}

\usepgfplotslibrary{patchplots}
\usepgfplotslibrary{fillbetween}

\pgfmathdeclarefunction{wave}{3}{\pgfmathparse{#1*18*exp(-x*x/#2)*sin(2*pi*x/#3)}}

\pgfplotsset{compat=1.16,
             scale only axis = true,
             trig format=rad,
             colormap={mycolors1}{cmyk(0)=(0.9,1,0.25,0.45)
                                  cmyk(180)=(0.9,1,0.25,0.45)
                                  cmyk(250)=(1,0,1,0.2)
                                  cmyk(260)=(0,0,1,0)
                                  cmyk(350)=(0,0,0,0)
                                  cmyk(1000)=(0,0,0,0)
                                 },
}

\begin{document}
\begin{tikzpicture}

\begin{axis}[
    hide axis,
    width=221 pt,
    height=150 pt,
    colormap name = mycolors1,
    view={0}{90},
]

\addplot3[
  patch,
  patch refines=1,
  shader=interp,
  samples=10,
  domain =-15:15,
  domain y=-15:15,
  on layer=axis background,
  point meta = (((x^2+y^2)*exp(-1*sqrt(x^2+y^2)/3))^2)*(3*(sin(x/sqrt(x^2+y^2))^2)-1)^2,
]
{0.0};

\addplot[
  red,
  name path=A,
  domain=-15:15,
  samples=100,
]
{wave(1.0,30,12.0)};

\addplot[
  red,
  name path=B,
  domain=-15:15,
  samples=100,
]
{-0.2*wave(1.0,30,12.0)};

\addplot[
  fill=red,
]
fill between[
  of=A and B,
];

\end{axis}
\end{tikzpicture}
\end{document}

The function with the background and fill

I realize that my method of producing the "background" image is likely suboptimal, so I am open to suggestions for improving it, but it is not my greatest concern here. Also, I have significantly reduced the resolution for quick debugging.

Thanks in advance for your help.

4
  • Welcome! The aim is to have the overlay as specified, but not necessarily produced in a single plot, right?
    – user194703
    Dec 31 '19 at 3:11
  • Thank you for the welcome :) I am not entirely sure what you mean by not producing them in a single plot. The background can be produced as a separate .pdf than the curve if that is easier. Ultimately, I can do the overlay in Adobe Illustrator. As long as I can get the background and the curve to be on output .pdfs with the correct dimensions, I should be fine.
    – Jason V
    Dec 31 '19 at 3:18
  • You can put the plots in separate \saveboxes and rescale them to get whatever you like. That is, you do not need separate pdfs. I'll be happy to spell this out after dinner if this sounds reasonable to you.
    – user194703
    Dec 31 '19 at 3:21
  • That sounds like it could be the solution. If you could spell it out explicitly, that would be very helpful (after you finish enjoying dinner, of course). Would it also resolve the difference between the curve without the fill and the curve with the fill? fill between seems to add more white space around the curve that I would like to not have. I want to have the filled curve go to the left and right edges without any additional whitespace and have the option of going to the top and bottom edges.
    – Jason V
    Dec 31 '19 at 3:28
1

Here is a proposal: use \saveboxes for the background and foreground plots, and scale them to the desired dimensions. \saveboxes "know" their dimensions, they are given by \the\wd<box> and \the\ht<box>, respectively, so the scaling factors are straightforward to obtain (see the below). AFAIK the issue regarding the bounding box of fillbetween has never been solved completely so I just added an appropriate \clip in the 2d plot. I use \sbox for the \saveboxes such that the code still works if you decide to use \documentclass[tikz]{standalone}.

\documentclass{standalone}
\usepackage[cmyk]{xcolor}
\usepackage{pgfplots}

\usepgfplotslibrary{patchplots}
\usepgfplotslibrary{fillbetween}

\pgfmathdeclarefunction{wave}{3}{\pgfmathparse{#1*18*exp(-x*x/#2)*sin(2*pi*x/#3)}}

\pgfplotsset{compat=1.16,
             scale only axis = true,
             trig format=rad,
             colormap={mycolors1}{cmyk(0)=(0.9,1,0.25,0.45)
                                  cmyk(180)=(0.9,1,0.25,0.45)
                                  cmyk(250)=(1,0,1,0.2)
                                  cmyk(260)=(0,0,1,0)
                                  cmyk(350)=(0,0,0,0)
                                  cmyk(1000)=(0,0,0,0)
                                 },
}
\newsavebox\ThreeDplot
\newsavebox\TwoDplot

\sbox\ThreeDplot{\begin{tikzpicture}

\begin{axis}[
    hide axis,
    width=221 pt,
    height=150 pt,
    colormap name = mycolors1,
    view={0}{90},
]

\addplot3[
  patch,
  patch refines=1,
  shader=interp,
  samples=10,
  domain =-15:15,
  domain y=-15:15,
  on layer=axis background,
  point meta = (((x^2+y^2)*exp(-1*sqrt(x^2+y^2)/3))^2)*(3*(sin(x/sqrt(x^2+y^2))^2)-1)^2,
]
{0.0};
\end{axis}
\end{tikzpicture}}


\sbox\TwoDplot{\begin{tikzpicture}
\begin{axis}[
    hide axis,
    width=221 pt,
    height=150 pt,
]
 % by hand 
\clip ([yshift=-\pgflinewidth]-15,-14) rectangle ([yshift=\pgflinewidth]15,14);
\addplot[
  red,
  name path=A,
  domain=-15:15,
  samples=100,
]
{wave(1.0,30,12.0)};

\addplot[
  red,
  name path=B,
  domain=-15:15,
  samples=100,
]
{-0.2*wave(1.0,30,12.0)};

\addplot[
  fill=red,
]
fill between[
  of=A and B,
];

\end{axis}
\end{tikzpicture}}
\begin{document}
\begin{tikzpicture}[nodes={inner sep=0pt,outer sep=0pt}]
 \node[xscale={221pt/\the\wd\ThreeDplot},yscale={150pt/\the\ht\ThreeDplot}]{\usebox\ThreeDplot};
 \node[xscale={221pt/\the\wd\TwoDplot},yscale={150pt/\the\ht\TwoDplot}]{\usebox\TwoDplot};
\end{tikzpicture}%
\end{document}

enter image description here

Or without clip but ymin and ymax.

\documentclass{standalone}
\usepackage[cmyk]{xcolor}
\usepackage{pgfplots}

\usepgfplotslibrary{patchplots}
\usepgfplotslibrary{fillbetween}

\pgfmathdeclarefunction{wave}{3}{\pgfmathparse{#1*18*exp(-x*x/#2)*sin(2*pi*x/#3)}}

\pgfplotsset{compat=1.16,
             scale only axis = true,
             trig format=rad,
             colormap={mycolors1}{cmyk(0)=(0.9,1,0.25,0.45)
                                  cmyk(180)=(0.9,1,0.25,0.45)
                                  cmyk(250)=(1,0,1,0.2)
                                  cmyk(260)=(0,0,1,0)
                                  cmyk(350)=(0,0,0,0)
                                  cmyk(1000)=(0,0,0,0)
                                 },
}
\newsavebox\ThreeDplot
\newsavebox\TwoDplot

\sbox\ThreeDplot{\begin{tikzpicture}

\begin{axis}[
    hide axis,
    width=221 pt,
    height=150 pt,
    colormap name = mycolors1,
    view={0}{90},
]

\addplot3[
  patch,
  patch refines=1,
  shader=interp,
  samples=10,
  domain =-15:15,
  domain y=-15:15,
  on layer=axis background,
  point meta = (((x^2+y^2)*exp(-1*sqrt(x^2+y^2)/3))^2)*(3*(sin(x/sqrt(x^2+y^2))^2)-1)^2,
]
{0.0};
\end{axis}
\end{tikzpicture}}


\sbox\TwoDplot{\begin{tikzpicture}
\begin{axis}[
    hide axis,
    width=221 pt,
    height=150 pt,
    ymin=-14,ymax=14 % by hand 
]
\addplot[
  red,
  name path=A,
  domain=-15:15,
  samples=100,
]
{wave(1.0,30,12.0)};

\addplot[
  red,
  name path=B,
  domain=-15:15,
  samples=100,
]
{-0.2*wave(1.0,30,12.0)};

\addplot[
  fill=red,
]
fill between[
  of=A and B,
];

\end{axis}
\end{tikzpicture}}
\begin{document}
\begin{tikzpicture}[nodes={inner sep=0pt,outer sep=0pt}]
 \node[xscale={221pt/\the\wd\ThreeDplot},yscale={150pt/\the\ht\ThreeDplot}]{\usebox\ThreeDplot};
 \node[xscale={221pt/\the\wd\TwoDplot},yscale={150pt/\the\ht\TwoDplot}]{\usebox\TwoDplot};
\end{tikzpicture}%
\end{document}
3
  • Thank you very much for this explicit implementation. The solution looks really good. My only remaining question is about the leftover white border. I can probably manage with it, but it would be even better if it could be removed to minimize the post-processing that I need to do.
    – Jason V
    Dec 31 '19 at 4:26
  • @JasonV My bad. I forgot to set the outer sep and inner sep of the nodes to 0. Fixed that now.
    – user194703
    Dec 31 '19 at 4:31
  • Wonderful, that is perfect. Thanks a ton for your help!
    – Jason V
    Dec 31 '19 at 4:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.