Date: Tue, 18 May 2004 14:36:47 -0700
Reply-To: Dale McLerran <stringplayer_2@YAHOO.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Dale McLerran <stringplayer_2@YAHOO.COM>
Subject: Re: Plotting spectrum colors
In-Reply-To: <2gv7hsF74gi6U1@uni-berlin.de>
Content-Type: text/plain; charset=us-ascii
Richard,
Thanks! That just goes to show why you were the recipient of
this years SAS-L MVS award! Congratulations on receiving that
award. It was well deserved.
I was paying too much attention to the figure showing color
definitions in terms of degrees of the wheel, percent lightness,
and percent saturation and did not read the text. Having read
the text and observing that gray scales can be determined with
saturation 00 and hexadecimal lightness, let me offer up my macro
for producing heat maps using either gray scale or color definitions.
Comments are most welcome!
%macro heatmap(data=, yaxis=, xaxis=, intensity=intensity, color=no);
/* Produce a heatmap for a rectangular matrix of X and Y values */
/* The heatmap represents a third dimension of intensity values */
/* through either a color spectrum or gray-scale spectrum. */
%let color=%upcase(&color);
/* determine min and max values of intensity variable */
proc means data=&data noprint;
var &intensity;
output out=min_max min=minval max=maxval;
run;
/* scale the data so that intensities have 90 distinct levels. */
data _scaled_;
retain minval maxval;
set &data;
if _n_=1 then set min_max;
&intensity = int(89*(&intensity-minval)/(maxval-minval));
run;
proc sort data=_scaled_;
by &yaxis &xaxis;
run;
/* Use 90 pattern statements to represent 90 rescaled values. */
/* 90 colors provide 4% increments around a color wheel. */
/* We can also produce 90 shades of gray. Shades of gray are */
/* not equally spaced in terms of lightness, though nearly so. */
%do k=1 %to 90;
%let deg=%sysfunc(putn(%sysfunc(mod(360+92-4*&k,360)),hex3.));
%if &color=NO %then %do;
%let light=%sysfunc(putn(%sysfunc(round((&k-1)*256/90)),hex2.));
pattern&k value=msolid color=h000&light.00;
%end;
%else %do;
pattern&k value=msolid color=h°.8080;
%end;
%end;
proc gcontour data=_scaled_;
plot &yaxis*&xaxis=&intensity / levels=0 to 89 by 1
nolegend pattern;
run;
quit;
%mend;
Here is a demonstration of the heatmap macro. In this demonstration,
there are 200 samples. We observe a spectrum for each sample.
Each spectrum is composed of 500 paired observations of some x-axis
variable (MZ) and a response variable measuring intensity (Y).
Spectra are highly correlated. They tend to have the same peaks
in the same regions. Note, though, that in the example presented
here we have two different sets of spectra. One set of 50 spectra
are offset from the other set of 150 observations by a shift in
the x-axis (MZ) variable.
The heat map is a plot of the spectrum for each observation looking
down on the spectrum from above and using color or gray scale to
represent the intensity. The higher the intensity (the nearer
the peak to the observer looking down from above, the closer to
red if a color spectrum is employed or white if a gray-scale
is employed. A different representation of the data is to plot
intensity (Y) by x-axis variable (MZ) using separate lines for
each spectrum. That is, rather than looking down on the spectra,
we look through the spectra. For comparison, I show this plot also.
data test;
ybase = -10;
do mz=1 to 515;
ybase = ybase + .06*rannor(1234579);
do sample=1 to 200;
y = (ybase + .025*rannor(1234579));
output;
end;
end;
run;
data test2;
set test;
if sample<=150 then do;
if mz<=500;
end;
else do;
if mz>15;
mz=mz-15;
end;
run;
options mprint;
%heatmap(data=test2, intensity=y, yaxis=sample, xaxis=mz, color=yes);
%heatmap(data=test2, intensity=y, yaxis=sample, xaxis=mz, color=no);
proc sort data=test;
by sample mz;
run;
symbol1 value=none i=join color=black repeat=150;
symbol2 value=none i=join color=magenta repeat=50;
proc gplot data=test2;
plot y*mz=sample / nolegend;
run;
quit;
Dale
--- "Richard A. DeVenezia" <radevenz@IX.NETCOM.COM> wrote:
> Dale McLerran wrote:
> > Hi folks,
> >
> > I am working on a macro to produce heat maps. Heat maps use either
> > a gray scale gradient or a color gradient to represent a third
> > dimension of some data. When using a color gradient, my
> intensities
> > should follow the colors of a rainbow. That is, low intensities
> > should be represented by violet and high intensities by red. I
> > thought that generating colors employing the HLS color system
> > (see http://v8doc.sas.com/sashtml/gref/zgscheme.htm) would be the
> > easiest way to follow the colors of the rainbow. If I understand
> > the HLS color system, violet begins at 90 degrees and red ends
> > at 90 degrees with direction of travel around the circle through
> > decreasing degrees. That led me to write the following code which
> > uses 90 pattern statements each at 4 degree offsets from the last
> > pattern statement going around the circle.
> >
> >
> snip
> >
>
> Hue is hex, not decimal. In
> > %let deg=%sysfunc(putn(%sysfunc(mod(360+92-4*&k,360)),z3.));
>
> replace z3. with hex3.
>
> Note: Some image devices restrict you to 256 colors.
>
> --
> Richard A. DeVenezia
> http://www.devenezia.com/downloads/sas/samples
=====
---------------------------------------
Dale McLerran
Fred Hutchinson Cancer Research Center
mailto: dmclerra@fhcrc.org
Ph: (206) 667-2926
Fax: (206) 667-5977
---------------------------------------
__________________________________
Do you Yahoo!?
SBC Yahoo! - Internet access at a great low price.
http://promo.yahoo.com/sbc/