2

I am interested in plotting a ball similar to the ones below:

Example sphere 1 Example sphere 2

where the color of the surface of the ball depends on the distance from a chosen point (where the vector arrow points to). How can I achieve the coloring? I have checked several resources regarding shading, but since TikZ seems to treat a 3D ball like a 2D object I find it hard to achieve an effect like this.

I am currently using this code from TikZ Examples to draw my sphere, but I would appreciate any recommendations for a better method that would allow for shading like that.

  • All I could see is that the sphere goes from red to blue. But how fast is it? Perhaps this would give you some idea. – Symbol 1 Nov 26 '15 at 16:46
  • @Symbol1 It doesn't really matter as long as it's some sort of a gradient. Your link does look useful but the comments say that this way of shading doesn't work in many PDF readers which could be problematic. Thanks anyway! – sps Nov 26 '15 at 16:57
3

With pgfplots, the keyword you're looking for is point meta: you can specify a formula, according to it's value the point on the sphere is colored:

Code

\documentclass[tikz, border=2mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\begin{document}
% Radius
\pgfmathsetmacro{\R}{5}
% Point components
\pgfmathsetmacro{\Px}{4}
\pgfmathsetmacro{\Py}{-1}
\pgfmathsetmacro{\Pz}{3}

\begin{tikzpicture}
    \begin{axis}
    [   view={45}{20},
        unit vector ratio=1 1 1,
    ]   \addplot3
        [   domain=0:180,
            y domain=0:360,
            surf,
            shader=interp,
            z buffer=sort,
            % Your distance formula goes here
            point meta={sqrt(pow(x-\Px,2)+pow(y-\Py,2)+pow(z-\Pz,2))},
            colormap/jet,
        ]
            ({\R*sin(x)*cos(y)},
             {\R*sin(x)*sin(y)},
             {\R*cos(x)});

        \draw[-latex] (-\R,0,0) -- (\R,0,0);
        \draw[-latex] (0,-\R,0) -- (0,\R,0);
        \draw[-latex] (0,0,-\R) -- (0,0,\R);

        \draw[-latex, very thick] (0,0,0) -- (\Px,\Py,\Pz);
    \end{axis}
\end{tikzpicture}

\end{document}

Output

enter image description here


Edit 1: If you want to keep the coordinate grid, there's a shader type faceted interp for that:

Code

\documentclass[tikz, border=2mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\begin{document}
% Radius
\pgfmathsetmacro{\R}{5}
% Point components
\pgfmathsetmacro{\Px}{4}
\pgfmathsetmacro{\Py}{-1}
\pgfmathsetmacro{\Pz}{3}

\begin{tikzpicture}
    \begin{axis}
    [   view={45}{20},
        unit vector ratio=1 1 1,
    ]   %\draw[-latex] (0,0,0) -- (\Px,\Py,\Pz);
        \addplot3
        [   domain=0:180,
            y domain=0:360,
            surf,
            shader=faceted interp,
            z buffer=sort,
            point meta={sqrt(pow(x-\Px,2)+pow(y-\Py,2)+pow(z-\Pz,2))},
            %opacity=0.95,
            colormap/jet,
            samples=30,
            samples y=60,
        ]
            ({\R*sin(x)*cos(y)},
             {\R*sin(x)*sin(y)},
             {\R*cos(x)});

        \draw[-latex] (-\R,0,0) -- (\R,0,0);
        \draw[-latex] (0,-\R,0) -- (0,\R,0);
        \draw[-latex] (0,0,-\R) -- (0,0,\R);

        \draw[-latex, very thick] (0,0,0) -- (\Px,\Py,\Pz);
    \end{axis}
\end{tikzpicture}

\end{document}

Output

enter image description here

  • Great answer, thank you. I've been playing around with this code and it looks like PGFPlots removes the coordinate grid on the surface when you add this color shading. Is there a way to have both? – sps Nov 27 '15 at 11:25

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.