# How to plot three-dimensional polar functions with pgfplots

I would like to plot the following functions with pgfplots:

I know how they are defined:

\sqrt{r}\sin\frac{\theta}{2}, \sqrt{r}\sin\frac{\theta}{2}\sin\theta,
\sqrt{r}\cos\frac{\theta}{2}, \sqrt{r}\cos\frac{\theta}{2}\sin\theta


but nothing else (for example the domain).

I'll post soon my solution (which is far from what I'm looking for), but I would like to now your opinion from now.

EDIT: here is my attempt to reproduce the first function:

\documentclass{scrbook}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.5.1}
\begin{document}

\begin{tikzpicture}
\begin{axis}[
xtick=\empty,
ytick=\empty,
ztick=\empty,
unbounded coords=jump,
]
surf,
faceted color=blue,
samples=20,
domain=-1:1, y domain=-5:0]
{sqrt(x^2+y^2)*sin(0.5*atan(y/x))};
\end{axis}
\end{tikzpicture}


and here is the result:

I know, it's very different from how it should be, but I don't know how to improve it.

-
I'm not really sure what the question is here. –  Joseph Wright Apr 15 '12 at 8:27
@mp87: I think you're more likely to get helpful answers if you edit your question to include your current approach and what you don't like about it. –  Jake Apr 15 '12 at 9:05
@JosephWright: I took the plots from an article, but I don't know how to reproduce them. –  mp87 Apr 15 '12 at 12:03
@Jake: You're right, in fact I usually add a MWE. But this time, when I posted the question, I didn't have the code with me. I decided to ask for help anyway because I thought that maybe someone could help me without further information. –  mp87 Apr 15 '12 at 12:04

You can plot polar functions by setting domain=<your theta domain>, y domain=<your r domain>, data cs=polar. Using this approach, the jumps in your functions will be plotted correctly.

In this example, I've used the same color range for all four plots (by setting point meta min and point meta max explicitly). That way, you can immediately see that the functions span different z-ranges. If you don't want that, just delete the point meta min/max keys.

If you want the plots to fill out the whole x/y plane, you'll need to stretch r accordingly. I've defined two functions here, stretch that does just that. It needs to be applied to both y coord trafo and to the function to be plotted. In conjunction with shader=interp, we're getting pretty close to the original plots:

Code for circular polar plots

\documentclass{article}
\usepackage{pgfplots}
\usepackage{amsmath}
\begin{document}
\pgfplotsset{
mp87's style/.style={
view={285}{30},
unit vector ratio*=0.707 1.5 1,
domain=0:360, samples=30,   % theta
y domain=0:9, samples y=8,  % r
x dir=reverse,
data cs=polar,
zmin=-3, zmax=3,
3d box=complete*,           % draw all box lines, "*" = draw grid lines also in front
point meta min=-3, point meta max=3,  % same colour scaling for all plots
grid=major,             % draw major grid lines
xtick=\empty,               % no x or y grid lines
ytick=\empty,
ztick=0, zticklabels={}, % one grid line at z=0
z buffer=sort
}
}

\begin{tikzpicture}
\begin{axis}[mp87's style, title=$\sqrt{r} \sin(\theta / 2)$]
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
\begin{axis}[mp87's style, title=$\sqrt{r} \cos(\theta / 2)$]
\end{axis}
\end{tikzpicture}\\[2ex]
\begin{tikzpicture}
\begin{axis}[mp87's style, title=$\sqrt{r} \sin(\theta / 2) \sin(\theta)$]
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
\begin{axis}[mp87's style, title=$\sqrt{r} \cos(\theta / 2) \sin(\theta)$]
\end{axis}
\end{tikzpicture}
\end{document}


Code for square polar plots

\documentclass{article}
\usepackage{pgfplots}
\usepackage{amsmath}
\begin{document}

\tikzset{
declare function={stretch(\r)=min(1/cos(mod(\r,90)),1/sin(mod(\r,90));}
}
\pgfplotsset{
mp87's style/.style={
view={285}{30},
unit vector ratio*=0.707 1.5 1,
x dir=reverse,
domain=0:360, samples=41,   % theta, with samples = 8*n+1
y domain=0:9, samples y=8,  % r
zmin=-3,zmax=3,
3d box=complete*,           % draw all box lines, "*" = draw grid lines also in front
grid=major,             % draw major grid lines
grid style={black, thick},
xtick=\empty,               % no x or y grid lines
ytick=\empty,
ztick=0, zticklabels={}, % one grid line at z=0
z buffer=sort,
colormap/jet,
every axis plot post/.style={opacity=0.8},
data cs=polar,
before end axis/.code={
\draw [/pgfplots/every axis grid](rel axis cs:0.5,0.5,0.5) -- (rel axis cs:0,0.5,0.5);
},
y coord trafo/.code=\pgfmathparse{y*(stretch(x))},
y coord inv trafo/.code=\pgfmathparse{y/(stretch(x))},
}
}

\begin{tikzpicture}
\begin{axis}[mp87's style, title=$\sqrt{r} \sin(\theta / 2)$]
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
\begin{axis}[mp87's style, title=$\sqrt{r} \cos(\theta / 2)$]
\end{axis}
\end{tikzpicture}\\[2ex]
\begin{tikzpicture}
\begin{axis}[mp87's style, title=$\sqrt{r} \sin(\theta / 2) \sin(\theta)$]
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
\begin{axis}[mp87's style, title=$\sqrt{r} \cos(\theta / 2) \sin(\theta)$]
\end{axis}
\end{tikzpicture}

\end{document}

-
I suppose you mean {sin(x)*y},{cos(x)*y} in the first sentence. –  Torbjørn T. Apr 15 '12 at 13:39
Yes, thank you! –  Jake Apr 15 '12 at 13:41
is the 3D-perspective projection view expected soon in Tikz? (instead of the current parallel projection one) –  pluton Apr 15 '12 at 14:21
@pluton There is a feature request for perspective views in pgfplots. The feature request has no schedule, though - it might need some time. –  Christian Feuersänger Apr 15 '12 at 17:53
@Jake @Torbj if I am not mistaken then the transformation should be {cos(x)*y}, {sin(x)*y)} in both the first sentence AND in the listing. Otherwise you would have exchanged x and y –  Christian Feuersänger Apr 15 '12 at 19:31

In addition to the good answer of Jake, I would point out that pgfplots can automatically handle input coordinates in polar form: you simply need to say that they are given in polar form by means of the data cs=polar key.

If you do that, you can omit the explicitly provided parametric form of Jake's answer, i.e. instead of

\addplot3  [surf, z buffer=sort] ({cos(x)*y}, {sin(x)*y}, {sqrt(y)*sin(x/2)});


you simply write

\addplot3  [surf, z buffer=sort,data cs=polar] {sqrt(y)*sin(x/2)};


Here, only the z expression has to be provided, together with data cs=polar. Pgfplots assumes that your final X and Y coordinates are (angle,radius) and they are converted to cartesian coordinates on-the-fly without touching the z value.

Note that the "polar" system is 2d, its transformation is only applied to the first two coordinates.

So, my suggestion is to stick with Jake's answer together with the simplification by means of the data cs=polar key.

-