Creating a white and black color function

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.

3 Answers

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]


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]


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}]]


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}]


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]


With DensityPlot you can do

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


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]


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

• As a curiosity, why Density plot is less clear than ContourPlot in general? – Taiki Bessho Sep 22 '18 at 23:13
• @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. – kglr Sep 22 '18 at 23:22
• @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. – kglr Sep 23 '18 at 19:37
• 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}] – xzczd Oct 1 '18 at 8:01
• Thank you @xzczd; adding Exclusions->None fixed the issue. – kglr Oct 1 '18 at 8:22

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@SimplifyPWToUnitStep@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}}]


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]]


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]]