15
$\begingroup$

Bug introduced in 8 or earlier and persisting through 11.0.1 or later


ListContourPlot uses the wrong colouring here:

res = Import["https://dl.dropboxusercontent.com/u/38623/res.wdx", "WDX"];

ListContourPlot[res, Contours -> Range[0.66, 0.9, 0.02], ColorFunction -> "Rainbow"]

enter image description here

The contour plot shows that the function value decreases around the bottom middle, even though it reaches its maximum there in reality.

The tooltips for the contour values between the red and orange regions are correct however: one contour shows 0.84 and the other 0.86. It's just the colouring that's wrong.

Compare

ListDensityPlot[res, ColorFunction -> "Rainbow"]

Mathematica graphics

What is the simplest, most convenient workaround for this problem? Also, is this a bug or am I missing something? Can anyone explain why this happens?

I do need these specific contour values. Interpolation + ContourPlot gives the exact same result:

if = Interpolation[res]

ContourPlot[if[x, y], {x, 0.1, 1}, {y, 7, 9.4}, 
 Contours -> Range[0.66, 9, 0.02], ColorFunction -> "Rainbow"]
$\endgroup$
1
  • 1
    $\begingroup$ If you don't need the contour tooltips: ListDensityPlot[res, ColorFunction -> "Rainbow", Mesh -> {Range[0.66, 0.9, 0.02]}, MeshFunctions -> {#3 &}, MeshStyle -> GrayLevel[0, 0.5]] $\endgroup$ Commented Oct 22, 2015 at 11:28

2 Answers 2

12
$\begingroup$

This seems like a bug of some kind to me. But replacing the second argument to Range with the very last contour you want to see, as a workaround, gives the same contours but with proper coloring

Grid[{ListContourPlot[res, Contours -> Range[0.2, #, 0.02], 
     ColorFunction -> "Rainbow", 
     PlotLegends -> Automatic] & /@ {.86, .90}}]

enter image description here

And the bug seems to go away if you increase the scale of your data by a factor of 10, but it shows a completely different wrong color if you decrease it by a factor of 10.

Grid@Partition[#, 3] &@
 Table[ListContourPlot[{#1, #2, x #3} & @@@ res, 
   Contours -> Range[x .2, x .9, x 0.02], ColorFunction -> "Rainbow", 
   ImageSize -> 300], {x, {.001, .01, .1, 1, 10, 100}}]

enter image description here

So apparently ListContourPlot and ContourPlot have trouble with their ColorFunctionScaling when the data is smaller than 1.

$\endgroup$
4
  • $\begingroup$ Thank you Jason! Interesting observation that the plot legends have the wrong colouring too! $\endgroup$
    – Szabolcs
    Commented Oct 22, 2015 at 9:22
  • 2
    $\begingroup$ It has to be some issue with the ColorFunctionScaling right? If it rescales the data properly, to lie between 0 and 1, then it should have no effect when you multiply the data by 10. $\endgroup$
    – Jason B.
    Commented Oct 22, 2015 at 9:24
  • $\begingroup$ @JasonB But the bug doesn't present when using ListDensityPlot. Maybe there is something wrong with the ListContourPlot itself? $\endgroup$
    – Silvia
    Commented Oct 22, 2015 at 13:11
  • $\begingroup$ @Silvia, yeah - it must have to do with how the contour plot interacts with the scaling function. Perhaps someone needs to go spelunking? $\endgroup$
    – Jason B.
    Commented Oct 22, 2015 at 13:45
8
$\begingroup$

The issue seems to be with colorfunction scaling, as a work around, turn it off and do our own interpolation in the ColorFunction:

 range = (res[[All, 3]] // Sort)[[{1, -1}]];
 int = Interpolation[Transpose[{range, {0, 1}}], 
   InterpolationOrder -> 1]; 

 ListContourPlot[res, Contours -> Range[0.66, 0.9, 0.02], 
    ColorFunctionScaling -> False, 
    ColorFunction -> (ColorData["Rainbow"][int[#]] &)]]

enter image description here

Trying to get to the bottom of this, here are the specific normalized values passed to the color function:

 cvals = Union[
     Reap[ListContourPlot[res, Contours -> Range[0.66, 0.9, 0.02],
       ColorFunction -> (Sow[#] &)]][[2, 1]]]

{0., 0.0937872, 0.186559, 0.279331, 0.372103, 0.464875, 0.557647, 0.650419, 0.743191, 0.835963, 0.865364, 0.928735, 1.}

and see where they are plotted:

 Row@Table[ ListContourPlot[res, Contours -> Range[0.66, 0.9, 0.02], 
   ColorFunction -> (If[# == cv, Red, Blue] &)] , {cv, cvals[[9 ;;]]}]

enter image description here

that bottom region is fed a "normalized" value of 0.865364.. which is in fact the actual average raw data value in that region (!) (That makes some sense of @JasonB's scaling observation )

One thing you see is the specified contour range is a tad large and produces a completely empty band. If you make the range Range[0.66, 0.86, 0.02] that fixes it too, but that should not really be a problem.

$\endgroup$

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.