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