3
$\begingroup$

What I want to get is a density plot where the color function is thresholded: if the value of a function is larger a threshold, the color function returns white; otherwise, black.

I found some tutorials about how to create gradient color functions, but didn't find one for any thresholded color function.

If any of you teach this, it would be greatly appreciated.

$\endgroup$
7
$\begingroup$

Update: An alternative way to use ContourPlot using threshold as the single Contour with the option ContourShading:

threshold = .5;    
ContourPlot[FractionalPart[y + Sin[x^2 + 3 y]], {x, -3, 3}, {y, -3, 3}, 
  Contours -> {threshold}, ContourShading -> {Black, White}, 
  Exclusions -> None, PlotPoints -> 90] 

enter image description here

Similarly, DensityPlot with MeshFunctions, Mesh and MeshShading options:

DensityPlot[FractionalPart[y + Sin[x^2 + 3 y]], {x, -3, 3}, {y, -3, 3}, 
 MeshFunctions -> {#3 &}, Mesh -> {{threshold}}, 
 MeshShading -> {Black, White}, PlotPoints -> 90, 
 Exclusions -> None, WorkingPrecision -> 10] 

enter image description here

And, a combination of Raster and Image:

Image @ Raster[Table[UnitStep[FractionalPart[y + Sin[x^2 + 3 y]] - threshold], 
 {y, -3, 3,  1/100}, {x, -3, 3, 1/100}]]

enter image description here

We get the same picture using Boole[FractionalPart[y + Sin[x^2 + 3 y]] >= threshold] instead of UnitStep[FractionalPart[y + Sin[x^2 + 3 y]] - threshold].

Original answer:

You can use ContourPlot with options Contours and ContourShading:

threshold = .5;
ContourPlot[y + Sin[x^2 + 3 y], {x, -3, 3}, {y, -3, 3}, 
  Contours -> {threshold}, ContourShading -> {Black, White}]

enter image description here

Another alternative is to use RegionPlot:

RegionPlot[y + Sin[x^2 + 3 y] <= threshold, {x, -3, 3}, {y, -3, 3} , 
 BoundaryStyle -> Black, PlotStyle -> Black, PlotPoints -> 100]

enter image description here

With DensityPlot you can do

DensityPlot[y + Sin[x^2 + 3 y] , {x, -3, 3}, {y, -3, 3}, 
  ColorFunction -> (Black &), RegionFunction -> (#3 <= threshold &)] 

enter image description here

You can also use DensityPlot with the option ColorFunction with large enough value for PlotPoints to get a similar picture the one above:

cf1 = If[# <= threshold, Black, White] &;
DensityPlot[y + Sin[x^2 + 3 y], {x, -3, 3}, {y, -3, 3}, 
  ColorFunction -> cf1, PlotPoints -> 250]

enter image description here

Using cf2 = Blend[{Black, White}, UnitStep[# - threshold]] &; in place of cf1 gives the same result.

$\endgroup$
  • $\begingroup$ As a curiosity, why Density plot is less clear than ContourPlot in general? $\endgroup$ – Taiki Bessho Sep 22 '18 at 23:13
  • 1
    $\begingroup$ @TaikiBessho, I meant the blending of colors, for example, DensityPlot[y + Sin[x^2 + 3 y], {x, -3, 3}, {y, -3, 3}, ColorFunction -> (If[# <= threshold, Black, White] &)] unless you use some additional trick. $\endgroup$ – kglr Sep 22 '18 at 23:22
  • 1
    $\begingroup$ @TaikiBessho, you might want to add the option MaxRecursion with a high enough value (say 7) to DensityPlot and RegionPlot. I don't know the internal workings of ContourPlot`. $\endgroup$ – kglr Sep 23 '18 at 19:37
  • 1
    $\begingroup$ Wait, the results given by the first 2 samples are wrong, aren't they?: Plot[FractionalPart[y + Sin[x^2 + 3 y]] /. x -> 0 // Evaluate, {y, -3, 3}] $\endgroup$ – xzczd Oct 1 '18 at 8:01
  • 1
    $\begingroup$ Thank you @xzczd; adding Exclusions->None fixed the issue. $\endgroup$ – kglr Oct 1 '18 at 8:22
3
$\begingroup$

You may consider Image and Binarize:

expr = FractionalPart[y + Sin[x^2 + 3 y]];

Binarize[Image@Reverse@Transpose@Table[expr, {x, -3, 3, 0.01}, {y, -3, 3, 0.01}], 0.5]

If you need the frame, ArrayPlot and UnitStep may be a better choice:

frame = DensityPlot[, {x, -3, 3}, {y, -3, 3}];

binarize = {x, threshold} \[Function] 
           Evaluate@Simplify`PWToUnitStep@Piecewise[{{1, x < threshold}}]

frame~Show~ArrayPlot[
  binarize[Table[expr, {x, -3, 3, 0.01}, {y, -3, 3, 0.01}]\[Transpose], 0.5], 
  DataReversed -> True, DataRange -> {{-3, 3}, {-3, 3}}]

Mathematica graphics

$\endgroup$
3
$\begingroup$

If one really wishes to use DensityPlot[] (even tho the other answers have already shown better approaches), you need to remember to set ColorFunctionScaling -> False before using a thresholded color function. In the following example, I combine GrayLevel[] and UnitStep[]:

With[{h = 1/2},
     DensityPlot[y + Sin[x^2 + 3 y], {x, -3, 3}, {y, -3, 3}, 
                 ColorFunction -> Function[z, GrayLevel[UnitStep[z - h]]], 
                 ColorFunctionScaling -> False, PlotPoints -> 205]]

monochrome thresholded plot

More generally, one can use Blend[] and Boole[] for such plots:

With[{h = 1/2},
     DensityPlot[y + Sin[x^2 + 3 y], {x, -3, 3}, {y, -3, 3}, 
                 ColorFunction -> Function[z, Blend[{Pink, Green}, Boole[z > h]]], 
                 ColorFunctionScaling -> False, PlotPoints -> 205]]

colored version

$\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.