Color Maps in Euler Math Toolbox

A user asked me, how to do color maps in Euler. There is no simple function for this, though I might add one for the next version. But experienced users should be able to do this on their own. Let me explain how.

test-002

Our ultimate aim is to do produce the plot above, which shows a grid of 50×50 0-1-normal distributed random values. The red squares are very low values, and the blue squares are very high values. Most of the values are green as expected.

We first make a function for black and white maps.

>function colormap (A) ...
$  w=window(); m=margin(0);
$  if !holding() then h=holding(1); endif; clg;
$  window([w[1],w[2],w[3]*0.85+w[1]*0.15,w[4]]);
$  setplot(1,cols(A),1,rows(A));
$  min=totalmin(A); max=totalmax(A); A=(A-min)/(max-min);
$  C=rgb(A,A,A);
$  plotrgb(C);
$  xplot(grid=4,<frame);
$  window([w[3]*0.9+w[1]*0.1,w[2],w[3],w[4]]);
$  setplot(1,2,min,max);
$  v=linspace(0,1,500)';
$  C=rgb(v,v,v);
$  plotrgb(C);
$  ygrid(ticks(min,max));
$  window(w); margin(m); holding(h);
$endfunction

Let me comment about the steps.

  • The first two lines start the plotting. The plot window will be a part of the full window with screen coordinates in the range of 0 to 1024. We note the old plot window for later to restore it at the end of the function. Moreover, we note the previous margin and set the margin to 0. This is the margin between the plot bounds and the actual plot. Then we turn holding on if necessary and clear the window.
  • Next, we make the window a little smaller by taking 85% of its width. This should be followed by a setplot command, setting the plot window.
  • Now we scale A and plot RGB values for with plotrgb(). We add grid values, but no grid lines or frame.
  • Next we take the rest of the window and plot the color scale in the same way.
  • Do not forget to restore everything at the end.

The result will be a black and white color map.

test-001

We took an exponential distribution here.

>colormap(randexponential(50,50)); ...
>title("Exponential distribution"); ...
>xlabel("n"); ylabel("m"):

To get the spectral coloring, we need a function, which converts values from 0 to 1 to spectral colors. This is done by using the vectors

\(v=[1,1,1], \quad w_1=[1,-1,0], \quad w_2=[1/2,1/2,-1].\)

These are orthogonal. Now we take

\(v_\alpha = \dfrac{1}{3} \left( v + \dfrac{\cos(\alpha)}{\sqrt{2}} w_1 + \dfrac{\sin(\alpha)}{\sqrt{3/2}} w_2 \right) \)

with a value alpha computed from x. The components of this vector are the RGB values belonging to x. Note that the RGB values always add to 1.

>function getspectral (x) ...
$  x=(x-0.15)/1.2+0.1;
$  co=cos(2*pi*x)/sqrt(2); si=sin(2*pi*x)/sqrt(1.5);
$  r=1+co+si/2; g=1-co+si/2; b=1-si; f=1/3;
$  return rgb(r*f,g*f,b*f);
$endfunction

If we add this to the colormap function, we get the following.

>function colormap (A, spectral=0) ...
$  w=window(); m=margin(0);
$  if !holding() then h=holding(1); endif; clg;
$  window([w[1],w[2],w[3]*0.85+w[1]*0.15,w[4]]);
$  setplot(1,cols(A),1,rows(A));
$  min=totalmin(A); max=totalmax(A); A=(A-min)/(max-min);
$  if spectral then C=getspectral(A); else C=rgb(A,A,A); endif;
$  plotrgb(C);
$  xplot(grid=4,<frame);
$  window([w[3]*0.9+w[1]*0.1,w[2],w[3],w[4]]);
$  setplot(1,2,min,max);
$  v=linspace(0,1,500)';
$  if spectral then C=getspectral(v); else C=rgb(v,v,v); endif;
$  plotrgb(C);
$  ygrid(ticks(min,max));
$  window(w); margin(m); holding(h);
$endfunction

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.