```Date: Tue, 18 May 2004 14:36:47 -0700 Reply-To: Dale McLerran Sender: "SAS(r) Discussion" From: Dale McLerran 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" 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/ ```

Back to: Top of message | Previous page | Main SAS-L page