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

0
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
  • 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

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.