# Plotting function with polygonal domain using pgfplots

I am trying to plot the product between a Heaviside function and a trigonometric function in the domain [-1,1]x[-1,1] using pgfplots. I can use Mathematica to obtain the required result (see image), but with pgfplots I get staircasing along the diagonal line as shown in this post. Is there a proper way to specify a domain of plotting in pgfplots? The Heaviside function is defined as Heaviside = If[x + y < 1/2, 1, 0]; in Mathematica.

The MWE for this problem and the result are

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

\pgfmathdeclarefunction{Heaviside}{2}{%
\pgfmathparse{#1+#2<-0.5 ? 0 : 1}%
}

\begin{document}
\begin{tikzpicture}

\begin{axis}[view={-30}{30}]

{-Heaviside(x,y)*sin(3*x*180/pi)};

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

• Welcome to TeX.SX! Please help us help you and add a minimal working example (MWE) that illustrates your problem. Reproducing the problem and finding out what the issue is will be much easier when we see compilable code, starting with \documentclass{...} and ending with \end{document}. Commented Sep 6, 2022 at 13:42

There is nothing wrong with the way you specify your domain: domain=-1:1, y domain=-1:1. A domain is the area over which the function is plotted. The problem comes from two things. Firstly PGFPlots does not do any analysis of the function unlike Mathematica. PGFPlots is after all not a math program but a package for plotting on top of a drawing program(TikZ) (yes TikZ is a drawing program). Secondly there are a finite number of points where the function is evaluated(sample points) and no accurate way to control where. The sample points are spaced evenly over the domain controlled with samples. The only other way is to use samples at=, but it can not help here to get finely spaced samples around the discontinuity.

One solution would be to plot the function several times in small rectangular domains along the discontinuity line with a high sample number. This would need manual consideration and care, and would not give a very good result.

The other way is do it manually layer by layer with clips like this:

\documentclass[tikz, border=1cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\usepgfplotslibrary{patchplots}
\begin{document}
\begin{tikzpicture}[line join=bevel]
\begin{axis}[view={-30}{30}]
\addplot3[surf, shader=faceted interp, domain=0:1, y domain=-1:1, samples=11, samples y=21, forget plot] {-sin(3*x*180/pi)};
\begin{scope}
\draw[clip] plot[domain=-1:0.5, smooth] (\x, -0.5-\x, {-sin(3*\x*180/pi)}) -- (0.5,-1,0) -- (-1,0.5,0) -- cycle;
\addplot3[patch, shader=interp, patch type=rectangle, patch refines=3, forget plot] coordinates { (-1,0.5,-1) (0.5,-1,-1) (0.5,-1,1) (-1,0.5,1)};
\end{scope}
\begin{scope}
\draw[clip] (-1,0.5,0) -- (0.5,-1,0) -- (-1,-1,0) -- cycle;
\addplot3[surf, domain=-1:1, y domain=-1:1, samples=21, forget plot] {0};
\end{scope}
\end{axis}
\end{tikzpicture}
\end{document}

• The solution works but I really had to put \pgfplotsset{compat=1.18} in the preamble because it wasn't working otherwise (I was getting warning Package pgfplots Warning: running in backwards compatibility mode (unsuitable tick labels; missing features). Consider writing \pgfplotsset{compat=1.18} into your preamble. Is your code then compatible with the newest version? Commented Sep 8, 2022 at 9:08
• I do not understand. My code has \pgfplotsset{compat=1.18} as it should have. Commented Sep 8, 2022 at 9:10
• When I change the angle it doesn't look good, I think the first two functions are not correct (see view={-30}{-60}) Commented Sep 8, 2022 at 9:26
• Everything is correct. When you change the angle, you change the order of the layers, and then you need to change the order and the clipping - it is a manual process as described. Commented Sep 8, 2022 at 9:31
• So the clips are basically only keeping whatever has been drown but within the domain of interest? Commented Sep 8, 2022 at 9:47