4
$\begingroup$

This is a quick follow up to my other question which I thought was different enough to warrant a separate post.

My Question

How do you plot a region (such as $f(x,y)>z$) on a 2D surface $g(x,y)=z$ and change the color of the region?

A Simple Example

f[x_, y_] := Sin[x] + Sin[y];
g[x_, y_] := y x Sin[x y];
img = RegionPlot[3/2 > f[x, y] > 1, {x, 0, 2}, {y, 0, 2}, 
  Frame -> False, PlotRangePadding -> None, PlotStyle -> Orange, 
  BoundaryStyle -> Black]
Plot3D[g[x, y], {x, 0, 2}, {y, 0, 2}, PlotStyle -> {Texture[img]}]

enter image description here enter image description here

So I have figured out how to overlay the region plot on the surface, but the only color the region appears is black. This is in spite that I specified the RegionPlot to be Orange. How can I change the region plot on the surface to anything but black.

Notes

  • If you have any questions or need clarification please ask.
  • Again this is a quick follow up on my previous question.
$\endgroup$
8
$\begingroup$

MeshFunctions + MeshShading

Plot3D[g[x, y], {x, 0, 2}, {y, 0, 2},
 MeshFunctions -> {f[#, #2] &}, 
 Mesh -> {{1, 3/2}}, 
 MeshShading -> {White, Orange}, 
 Lighting -> "Neutral"]

enter image description here

BoundaryDiscretizeGraphics

Get a single polygon from img using BoundaryDiscretizeGraphics and use it as the texture:

img2 = BoundaryDiscretizeGraphics[img, MeshCellStyle -> {2 -> Orange, 1 -> Black}, 
   ImagePadding -> 0, PlotRangePadding -> 0];

Plot3D[g[x, y], {x, 0, 2}, {y, 0, 2}, PlotStyle -> Texture[img2], 
 Mesh -> None, Lighting -> "Neutral"]

enter image description here

Plot3D + RegionFunction

Show[Plot3D[g[x, y], {x, 0, 2}, {y, 0, 2}, PlotStyle -> None, Mesh -> None], 
 Plot3D[g[x, y], {x, 0, 2}, {y, 0, 2}, PlotStyle -> Orange, 
  BoundaryStyle -> Black, Mesh -> None, RegionFunction -> (1 < f[#, #2] < 3/2 &)]]

enter image description here

ImageMultiply

Minimal change in OP's code that gives the desired result is to use Texture[ImageMultiply[img, White]] instead of Texture[img]:

Plot3D[g[x, y], {x, 0, 2}, {y, 0, 2}, 
 PlotStyle -> Texture[ImageMultiply[img, White]],
 Mesh -> None, Lighting -> "Neutral"]

enter image description here

Post-process RegionPlot output into 3D polygons:

You can use PlotStyle -> None in Plot3D and lift the 2D region plot surface to 3D replacing coordinate {x,y} with {x,y, g[x,y]}:

Show[Plot3D[g[x, y], {x, 0, 2}, {y, 0, 2}, PlotStyle -> None, Mesh -> None], 
 Graphics3D[Cases[img, GraphicsComplex[a_, b__] :> 
    GraphicsComplex[{##, g[##]} & @@@ a, b]]], Lighting -> "Neutral"]  

enter image description here

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you. This is an interesting approach, but can you do it with no meshes? $\endgroup$ – AzJ Mar 7 at 1:59
  • $\begingroup$ @AzJ, please see the update. $\endgroup$ – kglr Mar 7 at 2:05
  • $\begingroup$ @kglr As you will soon pass me in reputation I am happy to see that you are writing answers I would be proud to call my own. :-) $\endgroup$ – Mr.Wizard Mar 9 at 10:38
  • $\begingroup$ @Mr.Wizard, thank you for the kind words. A lot of my answers are in fact based on what i have learned from yours. Re passing you in reps, that sounds like you intend to keep the target fixed for a while longer (which, I hope, is not the case btw :). $\endgroup$ – kglr Mar 9 at 20:43
2
$\begingroup$

You may also try Piecewise: Something similar to this for defining Colorfunction of separate regions.

    colfn = Piecewise[{{Red, 3/2 > f[#, #2] > 1}, {White, True}}] &

    Plot3D[g[x, y], {x, 0, 2}, {y, 0, 2}, 
    PlotPoints -> 200, PlotRange -> All, ColorFunction -> colfn, 
    ColorFunctionScaling -> False, Mesh -> None]

Also, check Exclusions in the plot options.

| improve this answer | |
$\endgroup$

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.