BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
linlin87
Quartz | Level 8

Hi SAS community


I have heatmap of values (0-1). I have on a BY variable ("disease"). I want to do and I can't work out how:

  1. Fix the color range to be 0-1. Currently it is using the minimum value in my dataset to be white, maximum to be black. I want white=0 and Black=1.
  2. Fix the color range across BY groups. Obviously with 1. above, when I do BY statement, it changes color map across the BY groups because it not fixed at 1 and 0.
  3. I want 'color legend' for all plots to display the full range: 0 (white) to 1 (black)

Any help would be appreciate

 

proc template;
  define statgraph corrHeatmap;
   dynamic _Title;
    begingraph;
      entrytitle _Title;
      rangeattrmap name='map';
      endrangeattrmap;
      rangeattrvar var=r attrvar=r attrmap='map';
      layout overlay / 
        xaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear')) 
        yaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'));
        heatmapparm x = x y = y colorresponse = rsquare / 
          xbinaxis=true ybinaxis=true
          name = "heatmap" display=all colormodel=(white black);
        continuouslegend "heatmap" / 
          orient = vertical location = outside title="Pearson Correlation";
      endlayout;
    endgraph;
  end;
run;

proc sort data=fit;
by disease;
run;
 
proc sgrender data=fit template=corrHeatmap;
	by disease;
	dynamic _title="Correlation matrix";
run;
 

 

1 ACCEPTED SOLUTION

Accepted Solutions
DanH_sas
SAS Super FREQ

Using the RANGEATTRMAP is the best approach, but you're code needs a little adjustment:

1. The COLORMODEL option needed to be removed from the HEATMAPPARM statement. Instead, the RANGECOLORMODEL needs to be defined on the RANGE statement. Otherwise, there is no binding between the 0-1 range and the white-black color range

2. The RANGEATTRVAR needs to have the RSQUARE variable specified on the VAR option. This option points to the real column in the data. The ATTRVAR option specifies a new reference variable name. This variable (not the RSQUARE) should be used for the COLORRESPONSE on the HEATMAPPARM to create the correct binding.

3. The fake data is not required, so I removed it.

 

proc template;
  define statgraph corrHeatmap;
   dynamic _Title;
    begingraph;
      entrytitle _Title;
      rangeattrmap name='map';
      range 0.0-1.0 / rangecolormodel=(white black);
      endrangeattrmap;
      rangeattrvar var=rsquare attrvar=r attrmap="map";
      layout overlay /
        xaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'))
        yaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'));
        heatmapparm x = x y = y colorresponse = r /
          xbinaxis=true ybinaxis=true
          name = "heatmap" display=all ;
        continuouslegend "heatmap" /
          orient = vertical location = outside title="Pearson Correlation"
          VALUECOUNTHINT=11;
      endlayout;
    endgraph;
  end;
run;

/* make some example data */
data fit;
do disease = 1 to 2;
   do x = 0 to 3;
      do y = 0 to 3;
         rsquare = (disease + x**2 + y**2) / 25;   /* make range in [0, 1] */
         output;
      end;
   end;
end;
/* check that rsquare is in [0,1] */
proc means data=fit;
class disease;
var rsquare;
run;

proc sort data=fit;
by disease;
run;

proc sgrender data=fit template=corrHeatmap;
	by disease;
	dynamic _title="Correlation matrix";
run;

View solution in original post

3 REPLIES 3
Rick_SAS
SAS Super FREQ

Two suggestions:
1. Use the RANGE statement inside the RANGEATTRMAP/ENDRANGEATTRMAP block.

2. Add some fake data to each BY group to force the continuous legend to always display tick marks at 0 and 1. There might be a better way to do this. Maybe @DanH_sas knows a better way:

 


proc template;
  define statgraph corrHeatmap;
   dynamic _Title;
    begingraph;
      entrytitle _Title;
      rangeattrmap name='map';
      range 0-1;  /* set range to [0,1] */
      endrangeattrmap;
      rangeattrvar var=r attrvar=r attrmap='map';
      layout overlay / 
        xaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear')) 
        yaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'));
        heatmapparm x = x y = y colorresponse = rsquare / 
          xbinaxis=true ybinaxis=true
          name = "heatmap" display=all colormodel=(white black);
        continuouslegend "heatmap" / 
          orient = vertical location = outside title="Pearson Correlation"
          VALUECOUNTHINT=11;
      endlayout;
    endgraph;
  end;
run;


/* make some example data */
data fit;
do disease = 1 to 2;
   do x = 0 to 3;
      do y = 0 to 3;
         rsquare = (disease + x**2 + y**2) / 25;   /* make range in [0, 1] */
         output;
      end;
   end;
end;
/* check that rsquare is in [0,1] */
proc means data=fit;
class disease;
var rsquare;
run;

proc sort data=fit;
by disease;
run;

/* HACK: insert fake data for rsquare=0 and  rsquare=1 to fool the continuous axis legend */
data Fake;
do disease = 1 to 2;    /* need fake obs for each value of disease */
   rsquare = -1E-3; output;
   rsquare =  1+ 1E-3; output;
end;
run;

data NewFit;
   set Fake Fit;
   by disease;
run;

proc sgrender data=NewFit template=corrHeatmap;
	by disease;
	dynamic _title="Correlation matrix";
run;
DanH_sas
SAS Super FREQ

Using the RANGEATTRMAP is the best approach, but you're code needs a little adjustment:

1. The COLORMODEL option needed to be removed from the HEATMAPPARM statement. Instead, the RANGECOLORMODEL needs to be defined on the RANGE statement. Otherwise, there is no binding between the 0-1 range and the white-black color range

2. The RANGEATTRVAR needs to have the RSQUARE variable specified on the VAR option. This option points to the real column in the data. The ATTRVAR option specifies a new reference variable name. This variable (not the RSQUARE) should be used for the COLORRESPONSE on the HEATMAPPARM to create the correct binding.

3. The fake data is not required, so I removed it.

 

proc template;
  define statgraph corrHeatmap;
   dynamic _Title;
    begingraph;
      entrytitle _Title;
      rangeattrmap name='map';
      range 0.0-1.0 / rangecolormodel=(white black);
      endrangeattrmap;
      rangeattrvar var=rsquare attrvar=r attrmap="map";
      layout overlay /
        xaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'))
        yaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'));
        heatmapparm x = x y = y colorresponse = r /
          xbinaxis=true ybinaxis=true
          name = "heatmap" display=all ;
        continuouslegend "heatmap" /
          orient = vertical location = outside title="Pearson Correlation"
          VALUECOUNTHINT=11;
      endlayout;
    endgraph;
  end;
run;

/* make some example data */
data fit;
do disease = 1 to 2;
   do x = 0 to 3;
      do y = 0 to 3;
         rsquare = (disease + x**2 + y**2) / 25;   /* make range in [0, 1] */
         output;
      end;
   end;
end;
/* check that rsquare is in [0,1] */
proc means data=fit;
class disease;
var rsquare;
run;

proc sort data=fit;
by disease;
run;

proc sgrender data=fit template=corrHeatmap;
	by disease;
	dynamic _title="Correlation matrix";
run;
linlin87
Quartz | Level 8

Thank you Rick and Dan

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 551 views
  • 0 likes
  • 3 in conversation