# How can I represent the curved shape of a surface?

How can I give third dimension to the green surface, with shadings of color or light effects, using tikz or pgfplots?

The matter is that the green surface looks (is) flat as the red one, while I would like it to look like the plot of an arbitrary real function of two variables (over the domain in red). This is why I also would not mind pgfplots.

It does not really matter to see axes in transparency or not.

My latest code in Addendum 2.

Consider the following picture:

I would like my green surface to look like the blue one in this latter. I see that the blue surface has a different contour line than the orange one (it is not the same closed curve translated only) and this help rendering "volume". But to change this would not be a problem to me: I would like to understand instead how to shade the green surface in my picture the same way the blue one is in the second image.

This second picture is not as good as we can do with TikZ/PGF, but I think the shade of blue is shaped properly to give the idea of curvature. This is what I want to achieve, with any syntax.

The following is the best I could do so far (shading method is very weak...).

\documentclass[border=5mm,tikz=true]{standalone}

\usepackage{tikz,pgfplots}

\usetikzlibrary{decorations.shapes}

\begin{document}

\begin{tikzpicture}[scale=1.25]
\draw [dotted, fill=green!15] plot [smooth cycle] %
coordinates {(-1.14,-1)(-0.84, -.18) (-0.04, 0.3) (2.24, 0) %
(4.48, -0.56) (4.48, -1.46) (3.38,-1.84)(0.38, -1.28)};
\draw [dotted, fill=red!15] plot [smooth cycle] %
coordinates {(-1.04, 1.54) (-0.52, 2.66) (1.22, 3.22) %
(4.48, 2.1)(4.44, 1.14) (3.38, 0.98) (0.84, 2.26)};
%\shadedraw [color=red!15, inner color=red!5, outer color=red!15] (1,3) circle (2mm);
\draw [dotted, fill=red!15] plot [smooth cycle] %
coordinates {(-1.04, 1.54) (-0.52, 2.16) (1.22, 2.72) %
(4.48, 2.1)(4.44, 1.14) (3.38, 0.98) (0.84, 2.26)};
\draw[thick,->] (0,0) -- (-2,-1.5) node[below] {$x$};
\draw[thick,->] (0,0) -- (5,0) node[right] {$y$};
\draw[thick,->] (0,0) -- (0,3) node[above] {$z$};
\filldraw (4.2,3.2) node[left] {$z=f(x,y)$};
\draw [dashed] (3.2,-1) -- (3.2,1.1);
\draw [dashed, lightgray] (3.2,1.1) -- (3.2,2.2);
\filldraw (3.2,-1)circle (2pt) node[left] {$\left(x_0,y_0\right)$};
\filldraw (3.2,2.2)circle (2pt) node[left] %
{$\left(x_0,y_0,f\left(x_0,y_0\right)\right)$};
\end{tikzpicture}

\end{document}


I'll post updates, thank you for any hint.

Here's an hackish suggestion. Not very general, not very nice but does the job in a quick and dirty way. The alternative seems to specify the surface by hand and compute the "shadow" so that the drawinf is accurate. I think the key graphical feature to render the 3D structure of the surface is to draw its grid, which is done here by the shader.

Here I just clip with a 2D area the 3D drawing to give the illusion of a "random" border. The original surface is taken from here.

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots, filecontents}

\begin{filecontents*}{filename.txt}
0 0 1.36
1 0 1.50
2 0 1.60
3 0 1.69
4 0 1.77
5 0 1.80
6 0 1.76
7 0 1.68
8 0 1.58
9 0 1.41
10 0 1.24

0 1 1.46
1 1 1.60
2 1 1.73
3 1 1.83
4 1 1.92
5 1 1.97
6 1 1.95
7 1 1.86
8 1 1.73
9 1 1.55
10 1 1.37

0 2 1.54
1 2 1.69
2 2 1.84
3 2 1.97
4 2 2.07
5 2 2.12
6 2 2.11
7 2 2.02
8 2 1.87
9 2 1.68
10 2 1.49

0 3 1.56
1 3 1.74
2 3 1.92
3 3 2.07
4 3 2.18
5 3 2.25
6 3 2.24
7 3 2.14
8 3 1.99
9 3 1.80
10 3 1.59

0 4 1.56
1 4 1.74
2 4 1.96
3 4 2.13
4 4 2.25
5 4 2.32
6 4 2.31
7 4 2.22
8 4 2.07
9 4 1.86
10 4 1.63

0 5 1.56
1 5 1.74
2 5 1.95
3 5 2.14
4 5 2.27
5 5 2.34
6 5 2.33
7 5 2.24
8 5 2.09
9 5 1.88
10 5 1.64

0 6 1.52
1 6 1.71
2 6 1.92
3 6 2.09
4 6 2.22
5 6 2.29
6 6 2.28
7 6 2.20
8 6 2.06
9 6 1.87
10 6 1.65

0 7 1.45
1 7 1.66
2 7 1.85
3 7 2.00
4 7 2.11
5 7 2.18
6 7 2.18
7 7 2.11
8 7 1.98
9 7 1.80
10 7 1.61

0 8 1.37
1 8 1.56
2 8 1.73
3 8 1.87
4 8 1.97
5 8 2.04
6 8 2.04
7 8 1.98
8 8 1.87
9 8 1.71
10 8 1.55

0 9 1.29
1 9 1.41
2 9 1.57
3 9 1.72
4 9 1.82
5 9 1.87
6 9 1.87
7 9 1.83
8 9 1.74
9 9 1.62
10 9 1.47

0 10 1.17
1 10 1.25
2 10 1.41
3 10 1.55
4 10 1.65
5 10 1.70
6 10 1.70
7 10 1.66
8 10 1.58
9 10 1.48
10 10 1.34
\end{filecontents*}

\begin{document}
\begin{tikzpicture}
\begin{axis}[view={-20}{20}, grid=both, xmin=0, ymin=0, zmin=0]

\clip[
rounded corners=5,
x=1.1cm,y=.4cm,z=3cm,
yshift=.1cm, xshift=-.7cm
]
(.3,2) -- (0,1) -- (.5,.3) -- (1,.2) -- (2,1.3) -- (3.5,.5) --
(4.5,2) -- (3.5,3) -- (1.5,3.4) -- (1.5,2.5) --
cycle
[yshift=2.7cm]
(.3,2) -- (0,1) -- (.5,.3) -- (1,.2) -- (2,1.3) -- (3.5,.5) --
(4.5,2)
[rounded corners=0]
parabola[parabola height=1.1cm] cycle
;

\addplot3[surf, point meta=explicit] table [z expr=0, meta index=2] {filename.txt};

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


• ...Indeed (see my comment to your comment) this is like what I had in mind. Thank you! – MattAllegro Jun 20 '14 at 17:10

One solution is to use pgf-blur to create a blur shadow that resembles the depth. Also, you can segment the dashed line into two parts, one in from and one in the back with lighter color that helps to mimic the depth effect:

\documentclass[italian,12pt]{article}
\usepackage{amsfonts,amsmath,amssymb}
\usepackage{lmodern}
\usepackage{tikz,pgfplots}
\usetikzlibrary{decorations.shapes}

\begin{document}

\begin{tikzpicture}[scale=1.5]
\draw[thick,->] (0,0) -- (-2,-1.5) node[below] {$x$};% x axis
\draw[thick,->] (0,0) -- (5,-0) node[right] {$y$};% y axis
\draw[thick,->] (0,-0) -- (0,3) node[above] {$z$};% z axis

\draw [dotted, fill=red!15]% red plain surface
plot [smooth cycle]
coordinates {(-1,-1.45) (0,-.95) (2,-.45) (4,-.95) (2,-2.45) (1.5,-2.25) (1,-2.35) %
(0,-1.95)};

\draw [dashed] (3.2,-1) -- (3.2,1.2);% segment

plot [smooth cycle]
coordinates {(-1,.75) (0,1.25) (2,1.75) (4,1.25) (2,-.25) (1.5,-.05) (1,-.15) (0,.25)};

\draw [dashed, lightgray] (3.2,0.4) -- (3.2,1.2);% segment

\filldraw (3.2,-1) circle (2pt)% point (x,y,0)
node[left] {$\left(x_0,y_0,0\right)$};
\filldraw (3.2,1.2) circle (2pt)% point (x,y,f)
node[left] {$\left(x_0,y_0,f\left(x_0,y_0\right)\right)$};

\end{tikzpicture}

\end{document}


The trick of course are

\draw[dotted,fill=green!15,blur shadow={shadow yshift=-7em}]
% and
\draw [dashed, lightgray] (3.2,0.4) -- (3.2,1.2);% segment

• Thank you very much! But this was not the point: I would like the upper green surface to appear curved instead of flat. Can we shade the green color - e.g. from the center to the border - to obtain such effect with a similar option? Thanks again for your effort (upvoted!). – MattAllegro Jun 15 '14 at 21:44
• The transparency over the segment works great, anyway – MattAllegro Jun 15 '14 at 22:46
• I think I didn't understand your question correctly. I do however, see what you want after your edit. I think @Bordaigorl's suggestion is a good starting point. I will try to modify the answer to suite your needs later. – Pouya Jun 16 '14 at 7:45
• Right, that was not too clear in the beginning. I did one last edit to put explaination more in evidence. I saw Bordaigorl's and I wonder what if the domain is not square or rectangular but arbitrary/random... – MattAllegro Jun 16 '14 at 16:28

Update 2015

Inspired by the use of nonlineartransformations in this recent answer, one nice way to do in straight-edge TikZ what I had in mind back when I posted the question is, for example, the following.

\documentclass[border=5mm,tikz]{standalone}
\usetikzlibrary{decorations.shapes}

\usepgfmodule{nonlineartransformations}
\def\fluttertransform{%
\pgfgetlastxy\x\y
\pgfpoint{\x+sin(\y)}{\y+sin(\x)*(30-\x/2)+\x/10}
}

\begin{document}

\begin{tikzpicture}[scale=1.25]
\draw [dotted, fill=green!15] plot [smooth cycle] %
coordinates {(-1.14,-1)(-0.84, -.18) (-0.04, 0.3) (2.24, 0) %
(4.48, -0.56) (4.48, -1.46) (3.38,-1.84)(0.38, -1.28)};

\begin{scope}[yshift=33mm]
\pgftransformnonlinear{\fluttertransform}
\draw [dotted, fill=red!15] plot [smooth cycle] %
coordinates {(-1.14,-1)(-0.84, -.18) (-0.04, 0.3) (2.24, 0) %
(4.48, -0.56) (4.48, -1.46) (3.38,-1.84)(0.38, -1.28)};
% now the same coordinates as above
\end{scope}

\draw[->] (0,0) -- (-2,-1.5) node[below] {$x$};
\draw[->] (0,0) -- (5,0) node[right] {$y$};
\draw (0,0) -- (0,2.05);
\draw[->,gray] (0,2.05) -- (0,2.6) node[above] {$z$};
\filldraw (4.2,3.2) node[left] {$z=f(x,y)$};
\draw [dashed] (3.2,-1) -- (3.2,1.1);
\draw [dashed,gray] (3.2,1.1) -- (3.2,2.2);
\filldraw (3.2,-1)circle (2pt) node[left] {$\left(x_0,y_0\right)$};
\filldraw (3.2,2.2)circle (2pt) node[left] %
{$\left(x_0,y_0,f\left(x_0,y_0\right)\right)$};
\end{tikzpicture}

\end{document}


Anyway the choice of pgfplots, as in the accepted answer by @Bordaigorl, is definitely to be preferred over this amateur way.

• I am sure that using nonlineartransform is not amateur way at all! – Black Mild Jan 28 at 21:40