3D Polar Coordinate System – How to Use with TikZ

3dpgfplotstikz-pgf

I'm trying to draw a nice 3D surface plot of the "mexican-hat" Higgs potential. I would also love to mark some special points (like the minimum) of the curve with lines and arrows and stuff.

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{polar}

\begin{document}
    \begin{tikzpicture}
      \begin{axis}[
          data cs=polar,
          samples=30,
          domain=-180:180,
          y domain=0:10,
          declare function={
            higgspotential(\r)={-125*\r^2+\r^4};
          },
        ]
        \addplot3 [surf, shader=flat, draw=black, z buffer=sort] {higgspotential(y)};
        \pgfmathparse{sqrt(125*2/4)};
        \let\min\pgfmathresult
        \pgfmathparse{higgspotential(\min)};
        \let\minval\pgfmathresult
        \def\angle{4}
        \draw (axis cs:0,0,0) -- (axis cs:\angle,\min,0) -- (axis cs:\angle,\min,\minval);
        \draw (axis cs:0,0,0) -- (axis cs:2*\angle,\min,0) -- (axis cs:2*\angle,\min,\minval);
        \end{axis}
    \end{tikzpicture}
\end{document}

However, the result does not look like expected:

broken

The lines created with \draw do not seem to point to the minimum of the surface plot. I assume that I'm making some mistake in how I use the coordinate system. Can someone help me out to make the \drawn lines actually point to the minimum?

Best Answer

The thing is that the \draw commands still use the cartesian coordinate system because data cs=polar is a PGFPlots option. So you can either draw the lines with \addplot coordinates or you need to convert the polar coordinates to cartesian coordinates.

For more details have a look at the comments in the code

% used PGFPlots v1.14
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
    \usepgfplotslibrary{
        colorbrewer,
    }
    \pgfplotsset{
        % so there is no need to write `axis cs:' before each coordinate
        compat=1.11,
    }
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
%            % for debugging purposes only
%            % --> view from top to see, if the polar coordinates where
%            %     converted correctly
%            view={0}{90},
            data cs=polar,
            samples=30,
            domain=0:360,
            y domain=0:10,
            declare function={
                higgspotential(\r)={-125*\r^2+\r^4};
                % added functions to calculate cartesian coordinates from
                % polar coordinates
                pol2cartX(\angle,\radius) = \radius * cos(\angle);
                pol2cartY(\angle,\radius) = \radius * sin(\angle);
            },
            % just because I don't like the `jet' colormap
            colormap/GnBu,
        ]
            \addplot3 [surf,shader=flat,draw=black,z buffer=sort] {higgspotential(y)};
                % you can calculate stuff and directly store the result in a variable
                \pgfmathsetmacro{\min}{sqrt(125*2/4)};
                \pgfmathsetmacro{\minval}{higgspotential(\min)};
                % changed the angle to easier check the result
                \pgfmathsetmacro{\angle}{-45}

            % -------------------------------------------------------------
            % either draw the lines as `\addplot3's where still the
            % polar coordinates are used ...
            \addplot3 [green,thick] coordinates {
                (0,0,0) (\angle,\min,0) (\angle,\min,\minval)
            };
            \addplot3 [green,thick] coordinates {
                (0,0,0) (2*\angle,\min,0) (2*\angle,\min,\minval)
            };
            % -------------------------------------------------------------
            % ... or draw the lines with tikz/pgf's `\draw' command, which
            % uses the cartesian coordinate system
            %
            % apply the new functions to convert from polar to cart where necessary
            % (you need the curly braces to TeX doesn't get confused with the
            %  round brackets. For more details see
            %  <http://tex.stackexchange.com/a/64974>)
            \draw [red,thick,dashed] (0,0,0)
                -- ({pol2cartX(\angle,\min)},{pol2cartY(\angle,\min)},0)
                -- ({pol2cartX(\angle,\min)},{pol2cartY(\angle,\min)},\minval);
            \draw [red,thick,dashed] (0,0,0)
                -- ({pol2cartX(2*\angle,\min)},{pol2cartY(2*\angle,\min)},0)
                -- ({pol2cartX(2*\angle,\min)},{pol2cartY(2*\angle,\min)},\minval);
            % -------------------------------------------------------------

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

image showing the result of above code