Wrapping a list density plot on a sphere

dear all

I have a data set in the form of a list: {{Theta1,Phi1,f1},{Theta1,Phi1,f1} …} which i would like to represent in the form of a density/Contour plot on the surface of a sphere

i tried using

SphericalPlot3D[1, {t, 0, 2 Pi}, {p, 0, Pi},
ColorFunction -> Function[{x, y, z, t, p, r}, Hue[f[t, p]]],
Mesh -> 10, MeshFunctions -> {Function[{x, y, z, t, p, r}, f[t, p]]}]

but it doesn’t seem to work in my case

thanks in advance for your help

Dear Lei,

first you said that you have “data”, but then your own example makes use of a “function” - an analytic expression. Plotting data and functions require different graphical tools. So which is your case?

first thank you for your reply. yes, i have a data set in the form of a list having function values depending on theta and phi, i.e. { {0,0,1}, {Pi,0,2}, {0,Pi,3} … } which i would like to wrap on a sphere surface as a density plot. SphericalPlot3D was the only way i could find to do something similar but it doesn’t work with a data set. is there another way to do it?

I will make a noisy data set to imitate the format you have given:

data = Flatten[Table[{{x, y}, Cos[4 x] + Sin[2 y] + .1 RandomReal[]}, {x, 0, Pi + .1, .01}, {y, 0, 2 Pi + .1, .01}], 1];

Now there are two ways I see how we can put it as density on a sphere surface. For both we need Interpolation function:

f = Interpolation[data];

Now I will use ContourPlot. I could use ListDensityPlot but it would basically do the same thing but slower. So:

plt = ContourPlot[f[x, y], {x, 0, Pi}, {y, 0, 2 Pi}, 
  PlotRangePadding -> 0, Frame -> False, ColorFunction -> "Rainbow", Contours -> 15, ContourStyle -> Opacity[.2]]

Now the 1st method is to use Texture:

SphericalPlot3D[1 , {u, 0, Pi}, {v, 0, 2 Pi}, Mesh -> None, TextureCoordinateFunction -> ({#5, 1 - #4} &), 
 PlotStyle -> Directive[Texture[plt]], Lighting -> "Neutral", SphericalRegion -> True, RotationAction -> "Clip"]

2nd method is to use custom ColorFunction and MeshFunctions based on the Interpolation you got before:

SphericalPlot3D[1, {u, 0, ?}, {v, 0, 2 ?}, ColorFunction -> 
 Function[{x, y, z, u, v, r}, ColorData["Rainbow"][Rescale[f[u, v], {-2, 2}]]], 
 ColorFunctionScaling -> False, 
 MeshFunctions -> {Function[{x, y, z, u, v, r}, f[u, v]]}, SphericalRegion -> True, RotationAction -> "Clip", 
 MeshStyle -> Opacity[.3]]

They don’t come out exactly the same, but you can figure out which you like better and how you can improve them further.

Dear Vitaliy,

Thank you for your reply.

i tried your suggested solution but unfortunately it didn’t work in my case…

I am attaching a part of my data here, the format is {Theta,Phi,f}

indata= {
{0.000Pi, 0.000Pi, 0.600},
{0.000Pi, 0.033Pi, 0.320},
{0.500Pi, 0.033Pi, 0.405},
{1.000Pi, 0.033Pi, 0.328},
{1.500Pi, 0.033Pi, 0.406},
{0.150Pi, 0.144Pi, 0.093},
{0.350Pi, 0.144Pi, 0.115},
{0.650Pi, 0.144Pi, 0.095},
{0.850Pi, 0.144Pi, 0.151},
{1.150Pi, 0.144Pi, 0.150},
{1.350Pi, 0.144Pi, 0.102},
{1.650Pi, 0.144Pi, 0.115},
{1.850Pi, 0.144Pi, 0.084},
{0.000Pi, 0.206Pi, 1.541},
{0.050Pi, 0.206Pi, 1.165},
{0.450Pi, 0.206Pi, -1.403},
{0.500Pi, 0.206Pi, -1.505},
{0.550Pi, 0.206Pi, -1.449},
{1.450Pi, 0.206Pi, -1.415},
{1.500Pi, 0.206Pi, -1.468},
{1.950Pi, 0.206Pi, 1.153},
{0.189Pi, 0.256Pi, -1.197},
{0.311Pi, 0.256Pi, -0.757}
}

As you can see the internal step i am using isn’t necessarily regular since i am generating the data outside of mathematica.

for interpolation:
f = Interpolation;
i get the following error: “The coordinates do not lie on a structured tensor product grid”

and for:
f = Interpolation;
it just doesn’t do anything..

I wonder if the data structure is the reason? If so, I’m sorry i didn’t make it perfectly clear.
Is there a way to get around it?

Thank you again for your help.

Dan (Bai DaLei)

Yes, your data structure is wrong for Interpolation function. I would recommend first read documentation on functions you use and looking through examples given - you could literally use them to guide you. Documentation is very extensive. So in your case the ptoblem is fixed as

f = Interpolation[{{#[[1]], #[[2]]}, #[[3]]} & /@ indata, InterpolationOrder -> 1];

Then you plot becomes:

plt = ContourPlot[f[x, y], {x, 0, 6}, {y, 0, 0.8}, PlotRangePadding -> 0, 
Frame -> False, ColorFunction -> "Rainbow", Contours -> 15, ContourStyle -> Opacity[.2]]

The same plot you would get simply using:

plt = ListContourPlot[indata, InterpolationOrder -> All, PlotRangePadding -> 0, 
Frame -> False, ColorFunction -> "Rainbow", Contours -> 15, ContourStyle -> Opacity[.2]]

But now you have to be more careful with the rest, because you angle variables do not run complete spherical coordinate ranges {0, Pi} and {0, 2Pi}.

Dear Vitaliy,

Thank you again for your reply.

i guess i will have to re-generate my data and try to put it on a regular grid.

hopefully if will work after that.