1
$\begingroup$

Given data in the form

list={{{1,2},{3,4},{5,6}},{{7,8},{9,10},{11,12}},...}

a matrix where elements are 2-element vectors, what is a efficient way to plot this as a spatial grid? As I understand

ArrayPlot[array,ColorFunction->(If[#>3,Red,White]&), ColorFunctionScaling->False]

can only be "fed" with normal array (no 2-vector like above), if you want to use Colorfunction If condition.

I want that a cell of the ArrayPlot mesh gets Red, when in {x,y} vector 1<x<2 AND y>3, otherwise White.

I know I could recreate the list into a {{1,0,1},{0,1,0},...} like normal array so ArrayPlot could read it, by using Table and Take, 1 and 0 representing the Red and White Case:

If[1<First[Flatten[Take[list,i]]]<2,1,0]

Then rebuild that list with Table and Join. But as far as I know MM, there has to be easier way, simply reading list and replacing a 2-vector with 1 or 0 1-vector under above conditions. Or do I really have to build the list completely new, problem is it has some million elements.

Thanks for any tips to improve this

$\endgroup$
  • 1
    $\begingroup$ Try Map[(*your converting function*), list, {2}]. $\endgroup$ – Silvia May 5 '13 at 23:14
5
$\begingroup$

It appears you have lied to us about ColorFunction, see:

ArrayPlot[RandomReal[{0, 1}, {10, 10, 3}]] (*this works, therefore...*)
ArrayPlot[RandomReal[{0, 1}, {10, 10, 3}], ColorFunction -> Hue]

These work, therefore:

ArrayPlot[RandomReal[{0, 3}, {10, 10, 2}],
 ColorFunction -> (If[1 < #[[1]] < 2 && #[[2]] < 3, Red, White] &)]

enter image description here

Beautiful. But if we go the extra mile, we can get:

ArrayPlot[RandomReal[{0, 3}, {10, 10, 2}],
 ColorFunctionScaling -> False,
 ColorFunction -> (If[1 < #[[1]] < 2 && #[[2]] < 3, Red, White] &)]

enter image description here

The default for ColorFunctionScaling /. Options[ArrayPlot] is True, which screws up your values. Compare the following to see the difference:

ArrayPlot[RandomReal[{0, 3}, {2, 2, 2}], ColorFunctionScaling -> True, ColorFunction -> Print]
ArrayPlot[RandomReal[{0, 3}, {2, 2, 2}], ColorFunctionScaling -> False, ColorFunction -> Print]

It makes sense in general since typical color functions such as Hue and ColorData[...] go from 0 to 1, but I've found you can often get more useful coloring by disabling the scaling.

$$-$$

Note: Apparently, ColorRules isn't affected by ColorFunctionScaling. This makes sense since ColorRules is typically used for integer data.

ArrayPlot[RandomReal[{0, 3}, {10, 10, 2}],
 ColorRules -> {{x_, y_} /; 1 < x < 3 && y < 3 -> Red, _ -> White}]
$\endgroup$
4
$\begingroup$

There are several ways to do this. Here are two that came to mind although I am sure there are many more

newArray1=Map[If[1 < #[[1]] < 2 && #[[2]] > 3, 1, 0] &, list, {2}]

newArray2=Replace[list, {{a_, b_} /; 1 < a < 3 && b > 3 :> 1, {a_, b_} :> 0}, {2}]

GraphicsRow[
    ArrayPlot[#, ColorFunction -> (If[# == 1, Red, White] &)] & /@ {newArray1,newArray2}
]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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