3
$\begingroup$

I want to create a custom ColorFunction using RGBColor for my DensityPlot. A nice example is provided in the ColorFunction documentation under "applications".

I'm trying to get this coloring:

  1. If zero: set color to Black.
  2. If positive: increase Blue.
  3. If negative: increase Red.

My code looks like this:

DensColor[ z_ ] := RGBColor[If[z < 0, -z, 0], 0, (z + Abs[z])/2]
f[x_, y_] := x*y - 1
DensityPlot[f[x, y], {x, -2, 2}, {y, -2, 2}, PlotRange -> Full, ColorFunction -> DensColor, PlotLegends -> Automatic]

Unfortunately, it gives blue for positive (correct), but still some dark-blue for zero (wrong), and no red at all (wrong).

Can anyone explain why this isn't working as I expected?

$\endgroup$
5
  • 1
    $\begingroup$ Set ColorFunctionScaling->False $\endgroup$ Sep 21, 2014 at 14:15
  • 1
    $\begingroup$ Related here or here $\endgroup$ Sep 21, 2014 at 14:17
  • $\begingroup$ @bobthechemist thanks, that works now. I didn't find these related questions here (which now explain the issue). However, I dont understand why Wolframs example (which indeed has negative values) does not need ColorFunctionScaling. $\endgroup$ Sep 21, 2014 at 14:23
  • $\begingroup$ Try one of the documentation examples with ColorFunctionScaling to see the difference, for example [i.stack.imgur.com/Dud45.png]. $\endgroup$ Sep 21, 2014 at 14:32
  • $\begingroup$ With ColorFunctionScaling->True (which is the default), Mathematica delivers values to the color function that are scaled to lie between 0 and 1. This is also the range that the CoolColor function in the example expects. $\endgroup$ Sep 21, 2014 at 15:06

2 Answers 2

2
$\begingroup$

This is put an answer on record.

As bobthechemist noted in a comment, the OP's code only needs to be given the option ColorFunctionScaling -> False,. When this is done

DensColor[z_] := RGBColor[If[z < 0, -z, 0], 0, (z + Abs[z])/2]
f[x_, y_] := x*y - 1
DensityPlot[f[x, y], {x, -2, 2}, {y, -2, 2}, PlotRange -> Full, 
  ColorFunction -> DensColor,
  ColorFunctionScaling -> False,
  PlotLegends -> Automatic]

plot

$\endgroup$
1
$\begingroup$

Yet another possibility is to use Blend[] in conjunction with an appropriately scaled sigmoidal function that takes values in $(0,1)$. LogisticSigmoid[] is a particularly convenient function for this application:

DensityPlot[x y - 1, {x, -2, 2}, {y, -2, 2}, 
            ColorFunction -> (Blend[{Red, Black, Blue}, LogisticSigmoid[#]] &), 
            ColorFunctionScaling -> False, PlotLegends -> Automatic,
            PlotRange -> Full]

red, black, and blue/colors scaled just for you

$\endgroup$

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