8

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!

2
  • 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, 2018 at 15:31
  • Thanks for your MWE! I edited my answer accordingly.
    – user121799
    Nov 13, 2018 at 16:38

1 Answer 1

5

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

5
  • 2
    Thanks! Wilco; now I see why MWEs are so important. Nov 13, 2018 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. Nov 13, 2018 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, 2018 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. Nov 13, 2018 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, 2018 at 17:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .