3
$\begingroup$

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!

$\endgroup$
6
  • $\begingroup$ 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]] ] $\endgroup$
    – Szabolcs
    Jul 14, 2015 at 6:52
  • $\begingroup$ @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? $\endgroup$
    – user1337
    Jul 14, 2015 at 7:00
  • $\begingroup$ You could use Rescale[] (@Szabolcs ;) ) along with maybe the "RedGreenSplit" gradient. $\endgroup$ Jul 14, 2015 at 7:05
  • $\begingroup$ @Guesswhoitis. I'm afraid I'm not fluent enough in Mathematica to use your comment. $\endgroup$
    – user1337
    Jul 14, 2015 at 7:17
  • $\begingroup$ 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. $\endgroup$ Jul 14, 2015 at 7:20

2 Answers 2

4
$\begingroup$

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

plot

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – user1337
    Jul 14, 2015 at 6:54
4
$\begingroup$

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

Out

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

Out2

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]

Out3

$\endgroup$
3
  • $\begingroup$ Thanks Karsten. However, I'd like the colors to be darker at lower values, and not the other way around. $\endgroup$
    – user1337
    Jul 14, 2015 at 7:02
  • $\begingroup$ @user1337 like this one? $\endgroup$
    – Karsten7
    Jul 14, 2015 at 7:37
  • $\begingroup$ 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. $\endgroup$
    – user1337
    Jul 14, 2015 at 7:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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