4

This is a follow-up question to Plotting a function on a triangular domain using pgfplots.

I am interested in plotting three functions on a triangular domain, specifically

  1. x*y
  2. (2*x*x+2*x+2*y*y-2*y)/(2*x-2*y+4)
  3. x-y+1

on the triangle (-1, -1) -- (-1, 1) -- (1, -1).

Here's what I have:

\documentclass[10pt]{article}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
\begin{axis}[xlabel=$x$,ylabel=$y$,small,view={-45}{10},zmin=-1,zmax=1]
\clip (axis cs:-1,-1) -- (axis cs:-1,1) -- (axis cs:1,-1) -- cycle;
\addplot3[surf,color=gray,domain=-1:1,domain y=-1:1,faceted color=black,opacity=0.05] {x*y};
\addplot3[surf,color=red,domain=-1:1,domain y=-1:1,faceted color=red,opacity=0.05] {(2*x*x+2*x+2*y*y-2*y)/(2*x-2*y+4)};
\addplot3[surf,color=blue,domain=-1:1,domain y=-1:1,faceted color=blue,opacity=0.05] {x-y+1};
\end{axis}
\end{tikzpicture}
\end{document}

As you can see, you cannot see anything :) If I change

view={-45}{10}

to

view={0}{90}

you can see the plots. However, with the aforementioned view, you cannot. Why is that?

Cheers

Fabian
  • 85

1 Answers1

4

The key clip is a two-dimensional construct which is applied after the 3d projection. It is only applicable to 3d clipping for special cases.

What you want is a parameterized triangle. To this end, you have to find a map

X=X(s,t)
Y=Y(s,t)

for 0<= s <=1 and 0<= t <= 1 such that (X,Y) represents your desired triangle.

Let us focus on the simple case: the unit triangle with vertices (0,0), (1,0) and (0,1). A possibility to define X(s,t) and Y(s,t) is to use

X(s,t) = s
Y(s,t) = t* (1-s)

This nonlinear equation ensures that we can sample a matrix of values t, s and scale them such that they fit into the triangle. Naturally, one of the corners will receive lots of data points in this approach (feel free to experiment with a parametric plot with domain=0:1 and these values for X and Y).

In order to map this approach to your triangle, we can simply use a simple linear map as follows:

\documentclass{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.11}

\begin{document}
\begin{tikzpicture}
\begin{axis}[xlabel=$x$,ylabel=$y$,
    view={-45}{10},
    zmin=-1,zmax=1,
    variable=s,
    variable y=t,
    domain=0:1,
]
\def\triangleParamX{-1+ 2*s}
\def\triangleParamY{-1+ 2*(1-s)*t}
\addplot3[surf,color=gray,faceted color=black,opacity=0.05] (\triangleParamX,\triangleParamY,x*y);
\addplot3[surf,color=red,faceted color=red,opacity=0.05] (\triangleParamX,\triangleParamY,{(2*x*x+2*x+2*y*y-2*y)/(2*x-2*y+4)});
\addplot3[surf,color=blue,faceted color=blue,opacity=0.05] (\triangleParamX,\triangleParamY,{x-y+1});
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Here is the image with view={0}{90}:

enter image description here

Note that a parametric plot requires X(s,t), Y(s,t), and Z(s,t). In my solution, Z depends implicitly on s and t: it depends on x and y. This is a special feature of pgfplots: it defines the math variables x and y to the final numbers X(s,t) and Y(s,t), respectively. Consequently, we can define Z in terms of x and y (since pgfplots evaluates X and Y before Z). This is also the reason why I defined variable=s and variable y=t, otherwise the sampling variable and the resulting X and Y would overwrite each other.

  • 1
    Thank you @Christian for your detailed answer. I wasn't aware that clip is primarily for 2d clipping. This is now an elegant solution to my problem. Also, thank you for pgfplots; it's an excellent package! – Fabian Nov 23 '14 at 22:32