# Using the “TemperatureMap” color scheme to color a 3D spherical plot

Before all, I have read this question and others but it doesn't help me, I thought I understand the problem but actually not (see my post)

Controlling ColorFunctionScaling

I want to do a very simple thing which again looks very complicated on mathematica.

I have spherical datas (function depending on $$\theta$$ and $$\phi$$ that I want to plot using a color scale on a sphere).

However, the color scaling is not good : not all the colors available are used (if I use a TemperatureMap, it will only use the high temperature colors for example).

I know it is a problem of scaling, I tried to modify it but I'm stuck and I'm not sure to really understand the thing.

Here is my code :

The function I use for my example (my functions are more complicated than just a cos(theta)), so please don't consider "special properties" of cos to answer :

f[Theta_] := Cos[Theta]


Thus, what I expect : The plot takes a value of theta, it computes cos[theta]. It does it for all values of theta. Then, in the end, it will affect the blue color to the lowest value, the red color to the highest. And all the intermediates colors for the intermediates values. Of course the law of assigning the colors is a cos(theta) law

Because what I don't get in the answer given is that the function cos[theta] never appears in the call of the spherical plot3D, they ask for a dependance in theta for the color from what I understood. I agree that theta and cos[theta] are both increasing functions here, but it is not the same law so the variation of colors shouldn't be the same. So, cos[theta] should appear in the call of sphericalplot3D as it is the dependance I want. We could imagine $$f$$ beeing a complicated, non monotonous function of theta in a more general case for example.

The first code and the result :

SphericalPlot3D[1, {Theta, 0, \[Pi]}, {Phi, 0, 2*\[Pi]},
ColorFunction ->
Function[{x, y, z, Theta, Phi},
ColorData["TemperatureMap"][f[Theta]]], Mesh -> True,
Boxed -> False, PlotStyle -> Directive[Opacity[.8]],
ColorFunctionScaling -> True] I thought that because of the option ColorFunctionScaling True, mathematica would do the work to rescale my function between 0 and 1 before applying the color on it. But it doesnt work as I dont have any blue colors on my plot...

Anyway, I tried to do the job for mathematica by rescaling my data directly.

SphericalPlot3D[1, {Theta, 0, \[Pi]}, {Phi, 0, 2*\[Pi]},
ColorFunction ->
Function[{x, y, z, Theta, Phi},
ColorData["TemperatureMap"][(f[Theta] + 1)/2]], Mesh -> True,
Boxed -> False, PlotStyle -> Directive[Opacity[.8]],
ColorFunctionScaling -> True] $$(f[Theta] + 1)/2 = (Cos[Theta]+1)/2$$, thus it belongs to $$[0;1]$$.

And of course it doesnt work either.

Where is the problem ? I am getting crazy it should be simple to solve it.

In summary : Here, I expect my graphs to have colors going from blue to red. However as you can see not all of the color are used.

• I also got into this problem today. It seemed so counterintuitive at first.. – Macrophage Sep 25 '19 at 18:22

Allright, I think I found an answer to my problem.

Here is the code :

tt[theta_] := 0.2*Cos[theta]

SphericalPlot3D[1, {Theta, 0, \[Pi]}, {Phi, 0, 2*\[Pi]},
ColorFunction ->
Function[{x, y, z, Theta, Phi},
ColorData[{"TemperatureMap", {-0.2, 0.2}}][tt[Theta]]],
Mesh -> False, Boxed -> False, PlotStyle -> Directive[Opacity[.8]],
ColorFunctionScaling -> False]


Here is the result : As we can see I directly entered the function "tt" that I want to be responsible for the variation of colors.

To use the full range of colors, I have to put in the function ColorData the parameter : {"TemperatureMap", {-0.2, 0.2}} where the second element of this list represent the minimum value of the function tt, and the maximum value of this function.

It gives mathematica the two extrema to put the coldest and hottest colors.

However, I still do not understand why this code didn't work (see my original post):

f[Theta]:=Cos[Theta]

SphericalPlot3D[1, {Theta, 0, \[Pi]}, {Phi, 0, 2*\[Pi]},
ColorFunction ->
Function[{x, y, z, Theta, Phi},
ColorData["TemperatureMap"][(f[Theta] + 1)/2]], Mesh -> True,
Boxed -> False, PlotStyle -> Directive[Opacity[.8]],
ColorFunctionScaling -> True]


Indeed, here I renormalised the function $$f$$ so that it's value are between 0 and 1. So it should work... If anyone has an idea I am still interested to hear the answer.

• In the last one, the reason that it doesn't work is because you have ColorFunctionScaling -> True. This means that before your own rescaling function ever sees Theta, it has already been rescaled to run from 0 to 1. So now your colours will run from (Cos + 1)/2 == 1 to (Cos + 1)/2 == 0.770. With scaling set to False, your own scaling function will be fed values from 0 to Pi and your colours will run from (Cos + 1)/2 == 1 to (Cos[Pi] + 1)/2 == 0 giving you the full colour range. – MassDefect Jan 27 '19 at 3:51
• Also, in your first example, you could have ColorData["TemperatureMap", {-1, 1}][tt[Theta]] and tt[Theta_] := Cos[Theta] if you prefer. – MassDefect Jan 27 '19 at 3:52

It looks like the problem is that ColorFunctionScaling -> True results in Theta being scaled to run from 0 to 1 (normally it would run from 0 to Pi) before it's ever fed to your function. So it looks like your colours in the first graph are running from ColorData["TemperatureMap"][Cos] to ColorData["TemperatureMap"][Cos].

One option is to set scaling to true, but make the color a function of Theta only.

SphericalPlot3D[
1,
{Theta, 0, \[Pi]},
{Phi, -\[Pi], \[Pi]},
ColorFunction ->
Function[{x, y, z, Theta, Phi}, ColorData["TemperatureMap"][Theta]],
Mesh -> True,
Boxed -> False,
PlotStyle -> Directive[Opacity[.8]],
ColorFunctionScaling -> True
] I don't think this looks especially pretty, and my guess is that this isn't what you wanted. The problem is that it's linear with Theta, but being projected onto a curved surface. We can try this instead:

f[Theta_]:=(Cos[Theta]+1)/2

SphericalPlot3D[
1,
{Theta, 0, \[Pi]},
{Phi, -\[Pi], \[Pi]},
ColorFunction ->
Function[{x, y, z, Theta, Phi}, ColorData["TemperatureMap"][f[Theta]]],
Mesh -> True,
Boxed -> False,
PlotStyle -> Directive[Opacity[.8]],
ColorFunctionScaling -> False
] My guess is that this is closer to what you wanted. Notice that this time the scaling is set to False. We want the function to be fed values from 0 to Pi and we are manually rescaling the output of Cos[Theta] to fall in the range of 0 to 1.

• Thanks for the answer. I dont understand your last example, indeed the functiol f(theta) never appears in the spherical plot. Thus it seems that the colors are representing the value of theta and not the values of cos(theta) ? – StarBucK Jan 26 '19 at 6:50
• (If my question is not clear, look at the comment I made on the other answer, it may help to understand better my problem !) – StarBucK Jan 26 '19 at 6:55
• @StarBucK Hmmm, I'm afraid I don't understand. In the last example, the colour does explicitly depend on Cos[Theta] (that's what is defined in the f[Theta]...). In both graphs, the top is red. This is when Theta = 0 and therefore Cos[theta] = 1. At the very bottom of the sphere, Theta = Pi and Cos[Theta] = -1 is where it is most blue. I don't suppose you could post an example from the web of what colour scaling you want? These are the two colour scalings that I can think of that satisfy every single criteria you gave so far. – MassDefect Jan 26 '19 at 7:33
• Then forgive me its correct. What disturbs me is the definition of functiok f never appears in your 3D plot. Where is it taken in account I dont understand – StarBucK Jan 26 '19 at 9:02
• You define it before the plot but never call it in your sphericalplot3d line – StarBucK Jan 26 '19 at 9:03

### Edit

You should accept the default color function scaling. What you need to do to fix your problem is to give the correct arguments to ColorData expression you are using to define your color function.

Because it is not clear to me from your question how you want the colors from the temperature map to run along the sphere from the South Pole to the North Pole, I will give some choices along the same lines as @MassDetect gave.

### Colors mapped linearly as θ varies from 0 to 2 π.

Red at South Pole, blue at North Pole.

SphericalPlot3D[1, {θ, 0, π}, {ϕ, 0, 2 π},
ColorFunction -> (ColorData["TemperatureMap", "ColorFunction"][#4] &),
Boxed -> False,
PlotStyle -> Directive[Opacity[.6]]] Blue at South Pole, red at North Pole.

SphericalPlot3D[1, {θ, 0, π}, {ϕ, 0, 2 π},
ColorFunction -> (ColorData[{"TemperatureMap", "Reverse"}, "ColorFunction"][#4] &),
Boxed -> False,
PlotStyle -> Directive[Opacity[.6]]] ### Colors mapped linearly along the z-axis

Red at South Pole, blue at North Pole.

SphericalPlot3D[1, {θ, 0, π}, {ϕ, 0, 2 π},
ColorFunction -> (ColorData[{"TemperatureMap", "Reverse"}, "ColorFunction"][#3] &),
Boxed -> False,
PlotStyle -> Directive[Opacity[.6]] Blue at South Pole, red at North Pole.

SphericalPlot3D[1, {θ, 0, π}, {ϕ, 0, 2 π},
ColorFunction -> (ColorData["TemperatureMap", "ColorFunction"][#3] &),
Boxed -> False,
PlotStyle -> Directive[Opacity[.5]]] ### Update

This is in response to the OP's comments on the original answer. To get the behavior you ask for, you need to pass Cos[2 0] to the temperature map color function. The factor 2 is needed to get the whole range of the cosine function over the domain 0 to π, rather the range 0 to 2 π.

SphericalPlot3D[1, {θ, 0, π}, {ϕ, 0, 2 π},
ColorFunction -> (ColorData["TemperatureMap", "ColorFunction"][Cos[2 #4]] &),
Boxed -> False,
PlotStyle -> Directive[Opacity[.6]]] • I want the the bigger the value of cos(theta) is, the more red it shows. So when cos(theta)=1 it is the most red possible. When cos(theta)=-1 it is the more blue possible. And the colors change from blue to red with a cos(theta) dependance on the sphere. Here you made a linear dependance of evolution of the colors. Not a cos one. How to make a cos evolution (in practice my function will be a "complicated" function of theta and phi. – StarBucK Jan 26 '19 at 6:54
• Thanks for your answer also ! – StarBucK Jan 26 '19 at 6:54
• I edited my post with more details. – StarBucK Jan 26 '19 at 11:45