# DensityPlot3D with clear division negative/positive value but also value dependent

It is easy to obtain a clear positive/negative boundary, with, exemplary

ColorFunction -> Function[{f}, If[f > 0, Red, Blue]]


Do you have an idea how I can define a color function to get a clear division negative/positive value but also some info about the value?

When posting a question, provide a concrete example and the code used to demonstrate the issue.

One approach to clearly delineate the boundary is to use ContourPlot3D for the boundary

Show[
DensityPlot3D[x y z,
{x, -1, 1}, {y, -1, 1}, {z, -1, 1},
PlotLegends -> Automatic],
ContourPlot3D[x y z == 0,
{x, -1, 1}, {y, -1, 1}, {z, -1, 1},
ContourStyle -> Red]]


Whether one of the pictures satisfied you requirement?

fig1 = DensityPlot3D[x*y*z, {x, -1, 1}, {y, -1, 1}, {z, -1, 1},
ColorFunction -> Function[{f}, ColorData["TemperatureMap"][f]],
ColorFunctionScaling -> True];
fig2 = DensityPlot3D[x*y*z, {x, -1, 1}, {y, -1, 1}, {z, -1, 1},
ColorFunction -> Function[{f}, If[f > 0, Red, Blue]],
ColorFunctionScaling -> False];
fig3 = DensityPlot3D[x*y*z, {x, -1, 1}, {y, -1, 1}, {z, -1, 1},
ColorFunction -> Function[{f}, Blend[{Blue, Red}, f]],
ColorFunctionScaling -> False];


Making a custom plotting function based on Bob Hanlon's method combining DensityPlot3D and ContourPlot3D:

ClearAll[densityPlot3DwithContours]

SetAttributes[densityPlot3DwContours, HoldAll]

densityPlot3DwContours[f_, r1:{_,_,_}, r2:{_,_,_}, r3:{_,_,_}, o:OptionsPattern[]] :=
Show[DensityPlot3D[f, r1, r2, r3,
Evaluate@FilterRules[{o}, Options[DensityPlot3D]]],
ContourPlot3D[f, r1, r2, r3,
PlotLegends -> Automatic,
Evaluate @ FilterRules[DeleteCases[ColorFunction -> _]@{o},
Options[ContourPlot3D]],
Contours -> {{0., Opacity[.3, Red]}},
ContourStyle -> Automatic,
Mesh -> None,
BoundaryStyle -> None,
PlotPoints -> 70]]


Examples:

densityPlot3DwContours[x y z, {x, -1, 1}, {y, -1, 1}, {z, -1, 1},
PlotLegends -> BarLegend[Automatic, "StyledContours" -> {{0, Red}}]]


densityPlot3DwContours[x y z, {x, -1, 1}, {y, -1, 1}, {z, -1, 1},
ColorFunction -> "Rainbow",
Contours -> Thread[{{-.2, .1}, Opacity[.3, #] & /@ {Red, Green}}],
PlotLegends ->
BarLegend[Automatic, "StyledContours" -> Thread[{{-.2, .1}, {Red, Green}}]]]


I would prefer Bob Hanlon's approach as it is both simple and flexible. As an alternative approach we can also use a custom OpacityFunction to modify default opacity at function values close to 0:

ClearAll[customOpacity]
customOpacity[op1_: Automatic, op2_: .5] := If[.75 - .001 <= # <= .75 + .001, op2,
If[9/22 <= -1. + 2.*#1 < 7/11, .01, op1 /. Automatic -> .3, 0] ]& @
Rescale[#1, {0, 1}, {0.5, 1}] &


Examples:

DensityPlot3D[x y z, {x, -1, 1}, {y, -1, 1}, {z, -1, 1},
PlotLegends -> Automatic, OpacityFunction -> customOpacity[]]


Use OpacityFunction -> customOpacity[Automatic, 1] to get

OpacityFunction -> customOpacity[.5] to get

Add the option ColorFunction -> "Rainbow" to get

We can also use a custom ColorFunction:

defaultColorFunction = "DefaultColorFunction" /. (Method /.
ChartingResolvePlotTheme[Automatic, DensityPlot3D]);

ClearAll[customColor]
customColor[cf1_: Automatic, cf2_: Red] :=
If[.5 - .0001 <= # <= .5 + .0001, cf2,
(cf1 /. Automatic -> defaultColorFunction) @ # ] &  ;

DensityPlot3D[x y z, {x, -1, 1}, {y, -1, 1}, {z, -1, 1},
PlotLegends -> Automatic,
ColorFunction -> customColor[],
OpacityFunction -> customOpacity[]]


Use ColorFunction -> customColor[ColorData["Rainbow"]]` to get