Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a list of numbers, and I would like to plot them using ArrayPlot (which is easy, usually :)). I would like to be able to color the elements of the plot based on the average of the list: one color if the number is above average, another if it is below. I have tried a couple of things, but so far, no joy.

First thing I tried is have a module around the colorFun defined by me and the ArrayPlot, to calculate the mean, since I don't want it to be kernel-wide (many other plots will come with the same technique), and then define, inside the module, the colorFun:

  Module[
  {a, mean, colorFun},
    a = RandomInteger[{0, 100}, 100];
    mean = Mean[a];
    colorFun[z_] := If[z <= mean, Red, Blue];
    ArrayPlot[List@a, ImageSize -> Full, ColorFunction -> colorFun]
  ]

but this didn't work, since the plot would return all in the same color. It's actually not clear to me why.

I also tried to move colorFun in the form:

colorFun[z_]=RGBColor[{ , , }]    

with 2 functions of z and mean for two elements and 0 for the third. The idea of using this approach instead of the if is that I could blend the colors (the further from the average, the more intense/bright the color I am plotting with).

Any ideas?

Thanks!

share|improve this question
    
You need ColorFunctionScaling -> False... –  PlatoManiac Apr 23 '13 at 10:33
1  
...or rewrite colorFun[] so that it takes arguments in the interval $[0,1]$. –  J. M. Apr 23 '13 at 10:42
add comment

2 Answers 2

For concreteness, here's how one might do Plato's suggestion:

Module[{a, mid, colorFun},
       BlockRandom[SeedRandom[42]; (* for reproducibility *)
                   a = RandomInteger[{0, 100}, 100]];
       mid = Mean[a];
       colorFun[z_] := If[z <= mid, Red, Blue];
       ArrayPlot[{a}, ColorFunction -> colorFun, ColorFunctionScaling -> False]]

some array plot

To demonstrate the approach I proposed, I'll use it to implement your more fine-grained idea to have the color's intensity proportional to its distance from the mean, using Blend[]:

Module[{a, hi, lo, mid, colorFun},
       BlockRandom[SeedRandom[42];
                   a = RandomInteger[{0, 100}, 100]];
       {lo, mid, hi} = Through[{Min, Mean, Max}[a]];
       colorFun[z_] := Blend[{{0, Red}, {Rescale[mid, {lo, hi}], White}, {1, Blue}}, z];
       ArrayPlot[{a}, ColorFunction -> colorFun]]

another array plot with color intensity

share|improve this answer
    
Thanks! This providers a better scaling than my version. –  mgm Apr 23 '13 at 11:12
add comment

I am using this as a colorfunction:

colorFun[z_] := Blend[{Red, Darker@Green}, (z - 1)/mean];

and it's working more or less fine. Please, never mind the noise, but maybe it will be useful for somebody else. Also I am using, as suggested by PlatoManiac, ColorFunctionScaling->False.

Thanks!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.