I'm trying to use an external package, defined here. This package has a private function called makeColorFunction that essentially works by taking an input color function, written in terms of an undefined variable, and makes a pure function out of it by way of a replacement rule inside a call to Evaluate. Here is an example with Hue[Re[z]] given as the argument:

makeColorFunction[rhs_, z_] := 
          Function[Evaluate[(rhs  /. {Re[z] -> #1})]]

makeColorFunction[Hue[Re[z]], z]
(* Hue[#1] & *)

makeColorFunction is already written in the package that I am using, so I need to be able to just work with it, rather than change it.

I want to be able to feed this my own color functions that I usually make by using Blend, and it seems to work but gives an error:

colors = {#, 1 - #, #} & /@ Range[0, 1, .33];
myColorFunction = (Blend[RGBColor @@@ colors, #] &)
makeColorFunction[myColorFunction[Re@z], z]

During evaluation of Blend::argl: Re[z] should be a real number or a list of non-negative numbers, which has the same length as {,,,}. >>

During evaluation of Blend::argl: #1 should be a real number or a list of non-negative numbers, which has the same length as {,,,}. >>

(* Blend[{RGBColor[0., 1., 0.], RGBColor[
   0.33, 0.6699999999999999, 0.33], RGBColor[
   0.66, 0.33999999999999997`, 0.66], RGBColor[
   0.99, 0.010000000000000009`, 0.99]}, #1] & *)

So it does work in that it returns the expected pure function, but it gives an error. Since I would rather not use Quiet, I want another way to build up this color function.

The issue is that these two do not return an error,


while this does:

Blend[RGBColor @@@ colors, x]

In the end, I guess I would like to be able to make a ColorFunction that behaves in every way just like the built-in functions, but I don't know what attribute they possess that I need to add to my own.

I suppose this boils down to the question of why Hue can take symbolic arguments, but Blend cannot? Blend[{Red, Blue}, x] gives the error, but Hue[x] doesn't.


closed as off-topic by Jason B., WReach, Mr.Wizard Feb 17 '17 at 15:45

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "The question is out of scope for this site. The answer to this question requires either advice from Wolfram support or the services of a professional consultant." – Jason B., WReach, Mr.Wizard
If this question can be reworded to fit the rules in the help center, please edit the question.

  • $\begingroup$ This should work slightly better than Trott's version: SetAttributes[makeColorFunction, HoldAll]; makeColorFunction[rhs_, {z_, w_}] := Apply[Function, Hold[rhs] /. {Re[z] -> #1, Im[z] -> #2, Re[w] -> #3, Im[w] -> #4, Abs[z] -> Sqrt[#1^2 + #2^2], Abs[w] -> Sqrt[#3^2 + #4^2], Arg[z] -> ArcTan[#1, #2], Arg[z] -> ArcTan[#3, #4]}]. (I have taken the opportunity to restore the square roots where they ought to be.) $\endgroup$ – J. M. will be back soon May 17 '16 at 14:42
  • $\begingroup$ @J.M. But then I have to modify an in-package function. I was hoping there was some attribute I could set on myColorFunction that would make it behave like all the built-in color functions $\endgroup$ – Jason B. May 17 '16 at 14:49
  • $\begingroup$ I did try adding SetAttributes[makeColorFunction, HoldAll] to Trott's version, but no dice. Also, Blend[] evaluates instantly, so Blend[{Red, Blue}, z] quickly throws an error, as opposed to the *Color[] functions that are inert for nonnumeric arguments. $\endgroup$ – J. M. will be back soon May 17 '16 at 14:53
  • $\begingroup$ The first code block doesn't evaluate to the shown output. $\endgroup$ – Karsten 7. May 17 '16 at 15:34
  • 1
    $\begingroup$ maybe Inactive/Activate to prevent Blend from evaluating: myColorFunction = (Inactive[Blend][RGBColor @@@ colors, #] &) Plot[Sin[x], {x, 0, Pi}, ColorFunction ->Activate[ makeColorFunction[myColorFunction[Re@z], z]]], or Activate@Plot[Sin[x], {x, 0, Pi}, ColorFunction -> makeColorFunction[myColorFunction[Re@z], z]]? $\endgroup$ – kglr May 17 '16 at 20:20