2
$\begingroup$

I am plotting a function in 3D that takes integer values. I would like each integer height to appear as a different colour. There should be an easy way to do this but I am struggling with passing data to these colorfunctions. Does anyone have a suggestion? Thanks!

So far this is what I have got to work:

Plot3D[
  p[1][a, b, 0, 0, 0, 0],
  {a, 0, Pi/2},
  {b, 0, Pi/2}, 
  PlotRange -> All,
  ColorFunction -> "TemperatureMap"
] 

TemperatureMap does not change quickly enough for two adjacent integers. Is there a way to speed up its change? Or to define a new colorfunction that works as I describe?

An example of what I am thinking of is:

Plot3D[Position[{Round[a + b], Round[a - b]}, Min[{Round[a + b], Round[a - b]}]][[1]], {a, -1, 1}, {b, -1, 1}]

where it would be nice to have a unique colour for each of the two values this function takes (z=1 and z=2).

$\endgroup$
6
  • 1
    $\begingroup$ Do you have the definition of p? Do the colors need to have any continuity? Or just more or less "random" colors for each integer? Also, possibly related: (58951). And if the function takes integer values as you write, you might want to look at DiscretePlot3D $\endgroup$
    – Lukas Lang
    Apr 15, 2018 at 13:04
  • $\begingroup$ p[j_][[Tau]_, [Chi]_, [CapitalDelta]_, a_, b_, H_] := Position[Flatten[ Table[F[i][[Tau], [Chi], [CapitalDelta], a, b, H], {i, 1, 8}]], RankedMin[ Flatten[Table[ F[i][[Tau], [Chi], [CapitalDelta], a, b, H], {i, 1, 8}]], j]][[1]] for tables F[1] to F[8]. The colours don't need any continuity - I just want them to be as different as possible so that a bird's eye view of the plot will show a clear change in height. $\endgroup$
    – plotter
    Apr 15, 2018 at 13:18
  • $\begingroup$ Could you format your definition in such a way that it's usable? Also, F[1] to F[8] are missing... And did you look into using other plots to visualize the results (e.g. the suggested DiscretePlot3D or others)? Plot3D is really not designed for discrete data... If you really need to use Plot3D, you could do something like ColorFunction->ColorData[16],ColorFunctionScaling->False with any of the discrete color schemes $\endgroup$
    – Lukas Lang
    Apr 15, 2018 at 13:30
  • $\begingroup$ I input continuous variables and get out discrete values - is this not better to do with Plot3D than DiscretePlot3D? I'm not sure how to comment all of my code without it exceeding the allowed characters. $\endgroup$
    – plotter
    Apr 15, 2018 at 13:49
  • $\begingroup$ I assumed it also effectively takes integers (as you wrong "Tables F[1] to F[8] and "function in 3D that takes integer values")... You can always edit the question to put the code where it belongs - also it is always nice to provide a minimal example showing the problem, instead of the full code (i.e. try to make a simple function that is enough to demonstrate the issue) $\endgroup$
    – Lukas Lang
    Apr 15, 2018 at 13:52

1 Answer 1

1
$\begingroup$

The following should work:

Plot3D[
 Position[{Round[a + b], Round[a - b]}, Min[{Round[a + b], Round[a - b]}]][[1]],
 {a, -1, 1},
 {b, -1, 1},
 MaxRecursion -> 6,
 MeshFunctions -> {Ceiling@#3 + 0.001 &, #3 + 0.001 &, #1 &, #2 &},
 MeshShading -> ({{{#, Directive[Darker@#, [email protected]] & /@ #}}} &@ColorData[16, "ColorList"]),
 Mesh -> ({#, #, 10, 10} &@Range@10),
 MeshStyle -> {Directive[Thick, Black], Directive[Thick, Black], Automatic, Automatic},
 Exclusions -> None
 ]

Mathematica graphics

For a more interesting function:

Plot3D[
 Floor[2 Sin[a^2 + 2 b^2] + 2],
 {a, -2, 2},
 {b, -2, 2},
 MaxRecursion -> 6,
 MeshFunctions -> {Ceiling@#3 + 0.001 &, #3 + 0.001 &, #1 &, #2 &},
 MeshShading -> ({{{Darker /@ #, #}}} &@ColorData[16, "ColorList"]),
 Mesh -> ({#, #, 10, 10} &@Range@10),
 MeshStyle -> {Directive[Thick, Black], Directive[Thick, Black], Automatic, Automatic},
 Exclusions -> None
 ]

Mathematica graphics

An explanation of the different options:

  • MaxRecursion: Ensures that the edges of the plateaus are nice and sharp - increase/decrease as necessary
  • MeshFunctions: We're using Mesh to achieve the discrete colors instead of the blending done by ColorFunction. The mesh specifications produce four meshes, one at the bottom of the "walls", the other at the top (the +0.001 prevents the lines from missing at a few points due to rounding)
  • MeshShading: Specifies the color to use for the different regions. Here, we use one of the color lists (see ColorData for a more complete list) in normal form and with Darker to get the walls a bit different from the plateaus. The specification needs to be an array of depth 4 (as we have four meshes), where two meshes (x,y) shouldn't affect the color, hence the two single-element levels.
  • Mesh: Specifies the actual positions of the four meshes - for both z-meshes, we specify all integers (the range needs to be adjusted depending on the plot), for x,y we specify that 10 lines should be drawn.
  • MeshStyle: For the two z-meshes, we specify Directive[Thick,Black] to increase visibility, the other two (x,y) we leave alone
  • Exclusions: Needed to make sure the walls are plotted.
$\endgroup$
2
  • $\begingroup$ Thank you - that's very helpful. Is there any way to keep the mesh in the x-y directions or will that break this solution? $\endgroup$
    – plotter
    Apr 15, 2018 at 19:07
  • $\begingroup$ @plotter I've updated the answer with x/y meshes $\endgroup$
    – Lukas Lang
    Apr 15, 2018 at 19:58

Your Answer

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

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