11
$\begingroup$

Can anyone explain this (to me) odd behavior. If I run this code once (fresh kernel) it works as intended.

data = Table[Random[Real], {i, 5}, {j, 5}];
mycf[x_] := (AppendTo[hdat, x]; Hue[x])
hdat = {};
Show[Graphics[Raster[data, ColorFunction -> mycf]]]
Print["hdat len", Length[hdat]]
Histogram[hdat]

If I execute the same thing a second time the plot is generated but the hdat array is left empty. It seems some sort of caching is happening??

Edit - an even smaller example to illustrate the issue:

mycf[x_] := (value = 1; Hue[0])
value = 0
Show[Graphics[Raster[{{0}}, ColorFunction -> mycf]]]
value
    ------------next cell
value

Further clue... it turns out that any ColorFunction specified gets wrapped in Dynamic[]: If you do:

Graphics[Raster[{{0}}]]
Graphics[Raster[{{0}}, ColorFunction -> (Black &)]]

with dynamic updating disabled the first form works while the second does not. With that in mind, following Show[] in my example with FinishDynamic[] seems to do the trick.

$\endgroup$
2
  • $\begingroup$ I stuck a Pause[.05] in between the Graphics and Histogram and it worked as you would expect. $\endgroup$
    – amr
    Commented Sep 24, 2012 at 21:10
  • 1
    $\begingroup$ I'd have used Sow[]/Reap[] instead of AppendTo[] myself... $\endgroup$ Commented Sep 25, 2012 at 1:09

2 Answers 2

7
$\begingroup$

Certain things such as Graphics objects are handled by the Front End rather than the Kernel. An even simpler example of the behavior you question is this:

mycf[x_] := (Print["FE eval"]; Hue[0])
gr = Graphics[Raster[{{0}}, ColorFunction -> mycf]];

Upon evaluation nothing is printed, however if we then evaluate gr separately so that the graphic prints we also get "FE eval" printed to the Messages window. We get this every time gr is evaluated in a manner than displays the graphic. If we request the InputForm instead we see that the ColorFunction is held unevaluated in the expression:

gr // InputForm
Graphics[Raster[{{0}}, ColorFunction -> mycf]]

This expression is not further evaluated until it is passed to the FrontEnd (which calls the Kernel for evaluations beyond its scope).

$\endgroup$
1
$\begingroup$

Check this with Dynamic!

data = Table[Random[Real], {i, 5}, {j, 5}];
hdat = {};
mycf[x_] := (AppendTo[hdat, x]; Hue[x]);
GraphicsRow[{Show[Graphics[Raster[data, ColorFunction -> mycf]]], 
 Dynamic@Histogram[hdat, Frame -> True, 
 ColorFunction -> Function[{height}, Hue[height]], 
 AspectRatio -> 1, 
 PlotLabel -> "hdat length :" <> ToString[Length[hdat]]]}]

enter image description here

I guess ColorFunction is not responsible for the odd behavior. Once you evaluate the list hdat then it is available to the front end to display. This has to be done in a different cell or else some trick like the above. Or as chris commented by defining mycf differently mycf[x_] := (hdat=AppendTo[hdat, x]; Hue[x]) so that the symbol hdat is evaluated in the kernel each time the color-function is called.

BR

$\endgroup$
1
  • $\begingroup$ ahh that gives a clue. In fact if we acess the value in a new cell the updated value is available. So is this a Bug or an undocumenred feature? $\endgroup$
    – george2079
    Commented Sep 24, 2012 at 17:14

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.