7

I'm trying to render the following plot so that the shading goes right up to the bounding curve without this jagged aliasing.

an aliased rendering of a surface

The function is $\frac{x}{y^5 + 1}$ in the domain $\sqrt{x} \le y \le 2$ and $0 \le x \le 4$.

I translated this to PGFPlots as

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
    unbounded coords=jump,
    clip=false,
    view={-30}{45},
    axis lines=middle,
    xmin=0, xmax=4,
    ymin=0, ymax=2.15,
    zmin=0, zmax=0.5,
    xlabel=$x$, ylabel=$y$, zlabel=$z$,
    xtick={1, 2, 3, 4}, ytick={1, 2},
    ztick={0.5}, zticklabels={$\frac 1 2$}
]
\addplot3[
    samples=100, samples y=250,
    domain=0:4, domain y=0:2,
    colormap/blackwhite, shader=interp, surf, z buffer=sort
] {y >= sqrt(x) ? x / (y^5 + 1) : inf};
\addplot3[
    samples=100, domain=0:8
](
    {(x < 4) ? x : 8-x},
    {(x < 4) ? sqrt(x) : 2},
    {(x < 4) ? x / (sqrt(x)^5 + 1) : 0}
);
\addplot3[
    samples=100, domain=0:8
](
    {(x < 4) ? x : 8-x},
    {(x < 4) ? sqrt(x) : 2},
    {0}
);
\end{axis}
\end{tikzpicture}
\end{document}

and rendered it with LuaLaTeX.

It takes too long to render when I set samples and samples y high enough to make the aliasing disappear. What I want to do is something like samples at and put a bunch of samples near the edges and fewer in the midst, but samples at only allows you to set $x$ samples and not $(x,y)$ samples.

Any ideas? Thanks folks!

  • 3
    Welcome to TeX.SE! In order to encourage more users to look at your question, you may want to provide us with a complete MWE, i.e. a document that starts with \documentclass and ends with \end{document}. An ad hoc thought to increase the number of samples in the critical region is to do a parametric plot where now x and y are functions that are very flat in this region. – user121799 Nov 13 '18 at 15:31
  • Thanks for your MWE! I edited my answer accordingly. – user121799 Nov 13 '18 at 16:38
4

Thanks for your MWE!

Now to the real problem. You wish to plot the function only in the domain y >= sqrt(x). This can be achieved by doing a parametric plot. I constructed a functions ycheat(x,y), which, for a fixed x returns values in the interval between sqrt(x) and 2, which is the maximal value of y in your example. That is, if y varies between 0 and 2, ycheat runs only between sqrt(x) and 2. You thus get rid of your filter in y >= sqrt(x) ? x / (y^5 + 1) : inf as now simply no "bad" y occurs, and solve at the same time the issue with the boundary.

Last but not least let me mention that if you add samples y=1 to the 1-dimensional plots, this reduces the compilation time drastically.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{width=12cm,compat=1.16}
\begin{document}
\begin{tikzpicture}[declare function={ycheat(\x,\y)=sqrt(\x)+\y*(1-sqrt(\x)/2);}]
\begin{axis}[
    unbounded coords=jump,
    clip=false,
    view={-30}{45},
    axis lines=middle,
    xmin=0, xmax=4,
    ymin=0, ymax=2.15,
    zmin=0, zmax=0.5,
    xlabel=$x$, ylabel=$y$, zlabel=$z$,
    xtick={1, 2, 3, 4}, ytick={1, 2},
    ztick={0.5}, zticklabels={$\frac{1}{2}$}
]
\addplot3[samples y=1,% <-added
    samples=101, domain=0:4
](
    {(x < 4) ? x : 8-x},
    {(x < 4) ? sqrt(x) : 2},
    {0}
);
\addplot3[opacity=0.7,% <- added just for fun
     samples=101, samples y=25,
     domain=0:4, domain y=0:2,
     colormap/blackwhite, shader=interp, surf, z buffer=sort
 ] ({x},{ycheat(x,y)}, {x / (pow(ycheat(x,y),5) + 1)} );
\addplot3[samples y=1,% <-added
    samples=101, domain=0:4
](
    {(x < 4) ? x : 8-x},
    {(x < 4) ? sqrt(x) : 2},
    {(x < 4) ? x / (sqrt(x)^5 + 1) : 0}
);
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

  • 2
    Thanks! Wilco; now I see why MWEs are so important. – holomenicus Nov 13 '18 at 16:16
  • Ah, beautiful! I see you also fixed my typographic layout problems with the $y$ and $\frac 1 2$ $z$-tick by widening the figure. – holomenicus Nov 13 '18 at 16:49
  • @holomenicus I actually did not but will do this now, as well as drawing the curves first to get a more 3d like feel. – user121799 Nov 13 '18 at 16:53
  • I mean in the \pgfplotsset{width=12cm...; by default it is narrower and this causes the labels to overlap the surface; cf the picture in the OP. – holomenicus Nov 13 '18 at 16:56
  • @holomenicus I see. No, the width=12cm comes from the pre-MWE era, I simply added something and forgot to replace it by what you have. But if you like it, even better. I now changed the plot order and decreased the opacity of the surface. Whether this is really "better" is a matter of taste. The point of this answer is really only the parametric plot cheat. Quite possible it has been done on this site before, but I do not recall seeing it, yet this does not mean much. – user121799 Nov 13 '18 at 17:00

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.