2
$\begingroup$
r[\[Theta]_, \[Phi]_] := -1 ((Cos[\[Phi]] Sin[\[Theta]] Sin[\[Phi]] \
Sin[\[Theta]])^2 + (Sin[\[Phi]] Sin[\[Theta]] Cos[\[Theta]])^2 + \
(Cos[\[Phi]] Sin[\[Theta]] Cos[\[Theta]])^2);
{plot, points} = 
  Reap[SphericalPlot3D[
    r[\[Theta], \[Phi]], {\[Theta], 0, \[Pi]}, {\[Phi], 0, 2 \[Pi]}, 
    ColorFunction -> (ColorData["Rainbow"][Rescale[#6, {0, 1}]] &), 
    AxesStyle -> Thick, LabelStyle -> Directive[Black, Bold, Medium], 
    ImageSize -> 400, EvaluationMonitor :> Sow[r[\[Theta], \[Phi]] ]]];
Row[{plot, 
  DensityPlot[y, {x, -1, 1}, {y, Min@points, Max@points}, 
   ColorFunction -> "Rainbow", 
   FrameTicks -> {{None, All}, {None, None}}, 
   PlotRangePadding -> None, AspectRatio -> 15, 
   ImageSize -> {Automatic, 300}]}]

Why my result doesn't match my scale bar. The red part should have value -1/3 but it appears to be red. enter image description here

r[\[Theta]_, \[Phi]_] := -0.8 (Sin[\[Theta]]^2) + (Sin[\[Theta]]^4);
{plot, points} = 
  Reap[SphericalPlot3D[
    r[\[Theta], \[Phi]], {\[Theta], 0, \[Pi]}, {\[Phi], 0, 2 \[Pi]}, 
    ColorFunction -> (ColorData["Rainbow"][Rescale[#6, {0, 1}]] &), 
    AxesStyle -> Thick, LabelStyle -> Directive[Black, Bold, Medium], 
    ImageSize -> 400, 
    EvaluationMonitor :> Sow[r[\[Theta], \[Phi]]]]];
Row[{plot, 
  DensityPlot[y, {x, -1, 1}, {y, Min@points, Max@points}, 
   ColorFunction -> "Rainbow", 
   FrameTicks -> {{None, All}, {None, None}}, 
   PlotRangePadding -> None, AspectRatio -> 15, 
   ImageSize -> {Automatic, 300}]}]

And for this plot, r range from {-0.15,0.15}, but it seems SphericalPlot3D only treat abs value of r, how can I plot with {-0.15, 0.15} falls into "rainbow" range? enter image description here

n = 10
abc = RandomPoint[Sphere[{0, 0, 0}, 1], n]
r[\[Theta]_, \[Phi]_] := 
  Mean[Array[
    1 (1 - (abc[[#1, 1]] Cos[\[Phi]] Sin[\[Theta]] + 
          abc[[#1, 2]] Sin[\[Phi]] Sin[\[Theta]] + 
          abc[[#1, 3]] Cos[\[Theta]])^2) &, n]];
minr = MinValue[r[\[Theta], \[Phi]], {\[Theta], \[Phi]}];
maxr = MaxValue[r[\[Theta], \[Phi]], {\[Theta], \[Phi]}];
{plot, points} = 
  Reap[SphericalPlot3D[
    r[\[Theta], \[Phi]], {\[Theta], 0, \[Pi]}, {\[Phi], 0, 2 \[Pi]}, 
    ColorFunction -> (ColorData[
         "Rainbow"][(r[#4, #5] + Abs@minr)/(maxr - minr)] &), 
    ColorFunctionScaling -> False, AxesStyle -> Thick, 
    LabelStyle -> Directive[Black, Bold, Medium], ImageSize -> 400, 
    EvaluationMonitor :> Sow[r[\[Theta], \[Phi]] ]]];
Row[{plot, 
  DensityPlot[y, {x, -1, 1}, {y, Min@points, Max@points}, 
   ColorFunction -> "Rainbow", 
   FrameTicks -> {{None, All}, {None, None}}, 
   PlotRangePadding -> None, AspectRatio -> 15, 
   ImageSize -> {Automatic, 300}]}]

This doesn't work with @Domen 's solution, can anyone tell me why?

$\endgroup$
8
  • $\begingroup$ What if you just drop the Rescale and it will rescale automatically: ColorFunction -> (ColorData["Rainbow"][#6] &)? To remove the negative values, just wrap your function in the absolute value: r[\[Theta]_, \[Phi]_] := Abs[-0.8 (Sin[\[Theta]]^2) + (Sin[\[Theta]]^4)]; $\endgroup$
    – Domen
    Commented Aug 17, 2021 at 14:27
  • $\begingroup$ Thx for your reply, I want to keep the negative value. Because in this case r value range from (-0.2, 0.1), I want rescale (-0.2,0.1) to (0,1) then I can clearly know the r value (Representing energy) in each (r, ⍬, phi) points. $\endgroup$
    – Haodong
    Commented Aug 17, 2021 at 15:12
  • $\begingroup$ Okay, then you can manually rescale: min = MinValue[r[\[Theta], 0], \[Theta]]; max = MaxValue[r[\[Theta], 0], \[Theta]]; r[\[Theta]_, \[Phi]_] := (-0.8 (Sin[\[Theta]]^2) + (Sin[\[Theta]]^4) + Abs@min)/(max - min); $\endgroup$
    – Domen
    Commented Aug 17, 2021 at 15:21
  • $\begingroup$ Or as @Domen said at first, SphericalPlot automatically rescales the range to {0, 1}. So ColorFunction -> (ColorData["Rainbow"][#6] &) should be what you want. Look up ColorFunctionScaling in the documentation. $\endgroup$
    – Michael E2
    Commented Aug 17, 2021 at 15:25
  • 1
    $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Commented Aug 17, 2021 at 16:08

1 Answer 1

3
$\begingroup$

I think the problem lies in how SphericalPlot3D treats negative values for $r$. For example:

SphericalPlot3D[-Abs@Cos[2 \[Theta] ], {\[Theta], 0, \[Pi]}, {\[Phi], 
  0, \[Pi]}, ColorFunction -> (ColorData["Rainbow"][#6] &), 
 ColorFunctionScaling -> False]

Mathematica graphics

Even though all $r<0$, the points further away from the center are red, which means that SphericalPlot3D automatically makes $r$ positive when feeding it into ColorFunction. One solution to your problem can be to recalculate correct $r$ again in ColorFunction and rescale manually:

r[\[Theta]_, \[Phi]_] := -((Cos[\[Phi]] Sin[\[Theta]] Sin[\[Phi]] \
Sin[\[Theta]])^2 + (Sin[\[Phi]] Sin[\[Theta]] Cos[\[Theta]])^2 + \
(Cos[\[Phi]] Sin[\[Theta]] Cos[\[Theta]])^2);
minr = MinValue[r[\[Theta], \[Phi]], {\[Theta], \[Phi]}];
maxr = MaxValue[r[\[Theta], \[Phi]], {\[Theta], \[Phi]}];
{plot, points} = 
  Reap[SphericalPlot3D[
    r[\[Theta], \[Phi]], {\[Theta], 0, \[Pi]}, {\[Phi], 0, 2 \[Pi]}, 
    ColorFunction -> (ColorData[
         "Rainbow"][(r[#4, #5] - minr)/(maxr - minr)] &), 
    ColorFunctionScaling -> False, AxesStyle -> Thick, 
    LabelStyle -> Directive[Black, Bold, Medium], ImageSize -> 400, 
    EvaluationMonitor :> Sow[r[\[Theta], \[Phi]]]]];
Row[{plot, 
  DensityPlot[y, {x, -1, 1}, {y, minr, maxr}, 
   ColorFunction -> "Rainbow", 
   FrameTicks -> {{None, All}, {None, None}}, 
   PlotRangePadding -> None, AspectRatio -> 15, 
   ImageSize -> {Automatic, 300}]}]

Mathematica graphics

$\endgroup$
5
  • $\begingroup$ Genius, that is exactly want I want. Thanks Domen! $\endgroup$
    – Haodong
    Commented Aug 17, 2021 at 16:08
  • 1
    $\begingroup$ @Haodong I see that you have edited the question title of this post with “(Solved)”, but you’ve not marked this as an accepted answer. Can you, please, mark this as an accepted answer? Thanks! Generally, it is much better to indicate a question has been “solved” by accepting an answer, rather than editing the question title. $\endgroup$ Commented Aug 17, 2021 at 19:38
  • $\begingroup$ @CATrevillian Sure, sorry this is my first time posting a question, how can I mark as accepted, I can't find the where to click now. $\endgroup$
    – Haodong
    Commented Aug 18, 2021 at 3:42
  • $\begingroup$ @Haodong you should find a checkmark symbol near the question’s +1 and -1 vote buttons, clicking that will turn the checkmark green and “accept” the answer. $\endgroup$ Commented Aug 18, 2021 at 3:44
  • $\begingroup$ Thx, I did that. $\endgroup$
    – Haodong
    Commented Aug 18, 2021 at 3:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.