# An informative contour plot

I'm trying to visualise the graph of a function $f(x,y)$ of two real variables using ContourPlot. Here are the things I'm after:

• The points where $f(x,y)=0$ should be easily seen. This can be done with a separate ContourPlot of the form ContourPlot[f[x,y]==0,{x,x1,x2},{y,y1,y2}].

• There should be a clear distinction between the areas where $f(x,y)>0$ and $f(x,y)<0$. For example, the positive areas will coloured in shades of green, and the negative ones with shades of red.

• The plot should be symmetric with respect to the contour line $f(x,y)=0$. That is, if we're using different shades of green and red say, the points where $f(x,y)=10$ should have the same brightness as those where $f(x,y)=-10$.

To give an example, I'm not satisfied with the default

ContourPlot[y-x^2,{x,-5,5},{y,-5,5}]


since it's not easy to tell the positive and negative areas apart.

I would appreciate any help on this. Thanks!

• You can use ColorFunctionScaling -> False, which means that the values of the function will be directly passed to the colour function, without rescaling. Then you can identify where 0 is, precisely. But you need to write your own colour function. For example, Show[ DensityPlot[y - x^2 == 0, {x, -5, 5}, {y, -3, 7}, ColorFunction -> (ColorData["ThermometerColors"][ 1/2 + ArcTan[.2 #]/Pi] &), ColorFunctionScaling -> False, PlotPoints -> 50], ContourPlot[y - x^2 == 0, {x, -5, 5}, {y, -3, 7}, ContourStyle -> Directive[Black, Dashed]] ] Jul 14, 2015 at 6:52
• @Szabolcs Thanks! I'd like the transition from positive to negative to be sharper though, and also instead of the blue-red colors your picture has, use red-green respectively. Can this be done? Jul 14, 2015 at 7:00
• You could use Rescale[] (@Szabolcs ;) ) along with maybe the "RedGreenSplit" gradient. Jul 14, 2015 at 7:05
• @Guesswhoitis. I'm afraid I'm not fluent enough in Mathematica to use your comment. Jul 14, 2015 at 7:17
• To add to @Szabolcs's suggestion, you can skip the generation of the separate ContourPlot[] by adding Mesh -> {{0}}, MeshFunctions -> {#3 &}, MeshStyle -> Directive[Black, Dashed]. user, Szabolcs here asked a question about Rescale[]; try looking for it under his profile. Jul 14, 2015 at 7:20

As I understand your requirements, the following should meet them.

ContourPlot[x y^2 + x^3, {x, -5, 5}, {y, -5, 5},
Contours -> 15,
ColorFunction -> (If[# > .5, RGBColor[#, 0, 0], RGBColor[0, 1 - #, 0]] &)]


• Thank you! This seems to achieve what I'm after for this particular function. But if you use y-x^2 instead the change from green to red doesn't happen at the right contour. Jul 14, 2015 at 6:54

I'll use a Blend that is specified at three values, but you could use more.

With[{
blend :=
Blend[{{MinValue[{y - x^2, -5 < x < 5 && -5 < y < 5}, {x, y}],
Red}, {0,
Black}, {MaxValue[{y - x^2, -5 < x < 5 && -5 < y < 5}, {x, y}],
Green}}, #] &},
ContourPlot[y - x^2, {x, -5, 5}, {y, -5, 5}, ColorFunction -> blend,
ColorFunctionScaling -> False]
]


Adding two more Blend value specifications to reduce the extend of the black area:

With[{
blend :=
Blend[{{MinValue[{x y^2 + x^3, -5 < x < 5 && -5 < y < 5}, {x, y}],
Red}, {-1, Darker[Red, 0.85]}, {0,
Black}, {MaxValue[{x y^2 + x^3, -5 < x < 5 && -5 < y < 5}, {x,
y}], Green}, {1, Darker[Green, 0.85]}}, #] &},
ContourPlot[x y^2 + x^3, {x, -5, 5}, {y, -5, 5}, Contours -> 30,
ColorFunction -> blend, ColorFunctionScaling -> False]
]


As a function with symmetric coloring:

myCP[f_, {x_, xmin_, xmax_}, {y_, ymin_, ymax_}, opts : OptionsPattern[ListLogPlot]] :=
Module[{minmax =
Max[-MinValue[{f, xmin < x < xmax && ymin < y < ymax}, {x, y}],
MaxValue[{f, xmin < x < xmax && ymin < y < ymax}, {x, y}]],
blend},
blend = Blend[{{-minmax, Red}, {-minmax/100, Darker[Red, 0.9]}, {0, Black},
{minmax/100, Darker[Green, 0.9]}, {minmax, Green}}, #] &;
ContourPlot[f, {x, xmin, xmax}, {y, ymin, ymax}, opts,
ColorFunction -> blend, ColorFunctionScaling -> False]]

myCP[y - x^2, {x, -5, 5}, {y, -5, 5}, Contours -> 20]


• Thanks Karsten. However, I'd like the colors to be darker at lower values, and not the other way around. Jul 14, 2015 at 7:02
• @user1337 like this one? Jul 14, 2015 at 7:37
• I'm not completely satisfied with the first plot, but the second looks great. I'm going to test it for different functions f soon. Jul 14, 2015 at 7:47