MathGroup Archive 2005

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Combining a ListDensityPlot that uses a userdefined color function with a graphics 'looses' the userdefined colorfunction

  • To: mathgroup at smc.vnet.net
  • Subject: [mg59705] Re: [mg59683] Combining a ListDensityPlot that uses a userdefined color function with a graphics 'looses' the userdefined colorfunction
  • From: "David Park" <djmp at earthlink.net>
  • Date: Thu, 18 Aug 2005 00:16:36 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

Chris,

myArray = N[Table[Sin[x y], {x, 1, 40}, {y, 1, 40}]];

Let's look at both the min and max.

{Min[myArray], Max[myArray]}

Plot without change to the ColorFunctionScaling option.

ListDensityPlot[myArray, Mesh -> False]

Now plot with ColorFunctionScaling set to False This is probably NOT what
you really want since GrayLevel normally takes arguments between 0 and 1. So
this provides a false coloring. But I will show a case below where we do
want the ColorFunctionScaling to be False. In the meantime, let's go with
it.

plot1 =
  ListDensityPlot[myArray, Mesh -> False, ColorFunction -> GrayLevel,
    ColorFunctionScaling -> False]

Now let's convert plot1 from DensityGraphics to Graphics. This is what
happens when you add other graphics primitives and combine in a Show
statement but here we will just look at the density plot part. What happens
is that the DensityGraphics gets converted to a Raster function. The
ColorFunctionScaling gets lost. (Not the ColorFunction.)

plot2 = Show[Graphics[plot1]]

Let's look at the options for Raster. There are two of them.

Options[Raster]

And lets's look at what Mathematica actually produced. I omit the output but
you can evaluate and easily see (at the end) that in converting to Graphics
the WRI developers have copied in the ColorFunction option BUT FORGOT TO
COPY IN THE ColorFunctionScaling OPTION. Therefore the plot reverted to
ColorFunctionScaling set to False.

First[plot2]

I've complained to WRI about this for some time. It is a simple oversight
that could be easily corrected.  At first they said it was done 'by design'.
(Probably by 'Intelligent Design'?) But I kept complaining and the last I
heard was that it was referred to the developers. But good luck if they ever
change it.

A workaround is to insert back the ColorFunctionScaling option as in the
following statement.

Show[Graphics[plot1] /. Raster[args__, (opts__)?OptionQ] ->
    Raster[args, opts, ColorFunctionScaling -> False]]

The following combines the graphics with the Blue line.

Show[Graphics[plot1] /. Raster[args__, (opts__)?OptionQ] ->
    Raster[args, opts, ColorFunctionScaling -> False],
  Graphics[{Blue, Thickness[0.01], Line[{{10, 10}, {20, 20}}]}]]

Using the DrawGraphics package this could be done more directly, without
side plots, in the following way. We still have to correct for the missing
option. (If you don't have or like DrawGraphics skip this and continue on.)

Needs["DrawGraphics`DrawingMaster`"]

Draw2D[
 {ListDensityDraw[myArray, Mesh -> False, ColorFunction -> GrayLevel,
      ColorFunctionScaling -> False] /. Raster[args__, (opts__)?OptionQ] ->
      Raster[args, opts, ColorFunctionScaling -> False],
   Blue, Thickness[0.01],
   Line[{{10, 10}, {20, 20}}]},
  AspectRatio -> Automatic,
  Frame -> True];

Now, let's use a different color function. One that uses the named colors.
With this we really will want to use the ColorFunctionScaling -> False
option.

Needs["Graphics`Colors`"]

colorfun[z_] :=
  Which[
    z < -0.75, Gray,
    z < -0.5, LightCoral,
    z < 0.0, PaleGreen,
    z < 0.5, CadetBlue,
    z < 0.8, GeraniumLake,
    True, UltramarineViolet
    ]

ListDensityPlot[myArray, Mesh -> False, ColorFunction -> colorfun,
    ColorFunctionScaling -> False];

If you are using Version 5.1 or later, the above plot will produce errors
and incorrect colors. The reason has to do with dubious changes introduced
in 5.1. Instead of staying with a uniform and consistent scheme for named
colors, the system was completely fragmented. The named colors were all in
the standard package Graphics`Colors`. They were all RGBColors. One simply
had to load the package to obtain all the named colors. In Version 5.1 SOME,
but not all, of the named colors were moved to the kernel. That was the
first fragmentation. Now you can use some of the named colors without
loading the package. But which ones? Look it up. There was a second, worse
fragmentation. Some of the named colors, such as Gray and White were changed
from RGBColor to GrayLevel. This breaks the uniformity of the named colors
and broke any existing user code that depended on that uniformity. When they
were informed of this, before the release of Version 5.1 and not initially
by me, they said they weren't responsible for user's code.  When they were
asked what good reason there was for breaking the uniformity they replied
that it was 'for efficiency'. It is difficult to see that there is any
significant change in efficiency. But indeed, this change actually broke
their own code because Raster and RasterArray now no longer work with color
functions that involve a mix of named colors if some of these colors are
ones that have been changed to GrayLevel - as in the above example.

The WRI response to this is 'Don't use Gray.' ("Doctor, my arm hurts when I
raise it." "Then don't raise it.") Use the following...

colorfun[z_] :=
  Which[
    z < -0.75, RGBColor[0.5, 0.5, 0.5],
    z < -0.5, LightCoral,
    z < 0.0, PaleGreen,
    z < 0.5, CadetBlue,
    z < 0.8, GeraniumLake,
    True, UltramarineViolet
    ]

ListDensityPlot[myArray, Mesh -> False, ColorFunction -> colorfun,
    ColorFunctionScaling -> False];

And if WRI fixes this by changing Raster and RasterArray to check for
GrayLevel and RGBColors or always has to apply a conversion, what happens to
the so called 'efficiency' - not to speak of the efficiency of customer's
time on these unintuitive behaviors?

David Park
djmp at earthlink.net
http://home.earthlink.net/~djmp/



From: hopeandjoyandpeace at hotmail.com
To: mathgroup at smc.vnet.net
[mailto:hopeandjoyandpeace at hotmail.com]


Combining a ListDensityPlot that uses a userdefined color function with
a graphics 'looses' the userdefined colorfunction

for example

myArray=Table[Sin[x*y],{x,1,40},{y,1,40}]//N;
Max[myArray]
ListDensityPlot[myArray,Mesh-> False]

Show[ListDensityPlot[myArray,Mesh->False,ColorFunction->GrayLevel,ColorFunct
ionScaling->False],Graphics[{Blue,Thickness[0.01],Line[{{10,10},{20,20}}]}]]



Gives three density graphics but only one of them appears to uses the
colorfunction of GrayLevel.

We have version 5.1
How can I combine the image resulting when I define my own
colorFunction with another graphics without the image changing the way
it appears?


Chris
ABCC Regina



  • Prev by Date: Re: Some bugs in Mathematica
  • Next by Date: Re: Re: Simplification to Partial Fractions
  • Previous by thread: Re: Combining a ListDensityPlot that uses a userdefined color function with a graphics 'looses' the userdefined colorfunction
  • Next by thread: Problem behavior with FindMaximum