Download scattermatrix.sas scattermatrix.sasSubmit a comment

/*
 * Richard A DeVenezia
 * January 9, 2004
 *
 * Output a matrix of scatter plots, plotting every pair of variables.
 * No by group processing.
 */

%macro scatterMatrix (

  data=
, vars=
, plotOptions=          %* options to appened to plot statement;
, axis=                 %* nothing or NOAXIS;
, goutemp=work.scatplot %* intermediate output catalog (is replaced during execution);
, gout=work.scatter     %* graphics output catalog;
, name=scatrix          %* output catalog entry name;
, vnfont=               %* font for variable name boxes;
, border=               %* color of treplay panel border;
, symvalue=plus         %* symbol in plots;
, hsize=8               %* inches;
, vsize=8               %* inches;
, forcesize=1           %* should plots be generated at the same size they will be replayed at?;
, honorTitles=1         %* should current title and footnote be honored and shown in a background slide?;
, honorAxis=0           %* set to 1 if you want to use axis statements you setup prior to calling this;
, haxis=axis1
, vaxis=axis1
, topGap=7.5            %* pct of slide in vertical direction reserved - if honoring and titles present;
, bottomGap=5           %* pct of slide in vertical direction reserved - if honoring and footnotes present;
, hGap=0                %* horizontal % between panels ;
, vGap=0                %* vertical % between panels ;

);

  %local i nvar;
  %local hasT hasF hpct vpct h_size v_size;
  %local j row col n panel row col lowerX upperX lowerY upperY;

  %*-----
  %* extract variable names from vars
  %* no checks are done to ensure each name is a column in data
  %*;

  %let i = 1;
  %do %while (%scan(&vars,&i) ne );
    %local var&i;
    %let var&i = %scan(&vars,&i);
    %let i = %eval(&i+1);
  %end;
  %let nvar = %eval(&i-1);

  %*-----
  %* generate background slide
  %*;

  goptions goutmode=replace nodisplay;

  %let hasT = 0;
  %let hasF = 0;

  %if (&honorTitles = 1) %then %do;

    proc gslide gout=&goutemp name="BG";
      goptions reset=note;
      note  " ";
    run;
    quit;

    goptions goutmode=append;

    proc sql;
      reset noprint;
      select sum(type='T')>0, sum(type='F')>0
      into :hasT, :hasF
      from dictionary.titles
      ;
    quit;

    %let topGap    = %sysevalf (&hasT * &topGap);
    %let bottomGap = %sysevalf (&hasF * &bottomGap);

  %end;
  %else %do;
    %let topGap = 0;
    %let bottomGap = 0;
  %end;

  %*-----
  %* create scatter plots
  %*;

  title;
  footnote;

  %put NOTE: TITLES and FOOTNOTES have been cleared.;

  %if (&honorAxis = 0) %then %do;

    axis1 major=none minor=none label=none value=none;

  %end;

  symbol1 v=&symvalue i=none;

  %*-----
  %* determine size of panels
  %*;

  %let hpct = %sysevalf ((100 - &hGap*(&nVar-1)) / &nVar);
  %let vpct = %sysevalf ((100 - &vgap*(&nVar-1) - &topGap - &bottomGap) / &nVar);

  %let h_size = %sysevalf (&hsize * &hpct/100);
  %let v_size = %sysevalf (&vsize * &vpct/100);

  %if (&forcesize) %then %do;

    goptions hsize=&h_size.in vsize=&v_size.in;

  %end;

  %*-----
  %* create scatter plots, pairing each variable
  %*;

  proc gplot data=&data gout=&goutemp;
    %do row = 1 %to &nvar;
    %do col = 1 %to &nvar;
      plot &&var&row * &&var&col
         / haxis=&haxis vaxis=&vaxis
           name="_&row._&col."
           &plotOptions
         ;
      run;
    %end;
    %end;
  quit;

  %*-----
  %* slides for var * var panel
  %*;

  goptions goutmode=append;

  %do row = 1 %to &nvar;
    proc gslide gout=&goutemp name="_&row";
      goptions reset=note;
      note move=(45pct,45pct) h=25pct
           %if %length(&vnfont) %then
           f=&vnfont
           ;
           "&&var&row"
      ;
    run;
  %end;
  quit;

  %*-----
  %* replay the plots and slides
  %* create an n x n panel template (tdef) and treply the plots into the panels;
  %*;

  goptions hsize=&hsize.in vsize=&vsize.in;
  goptions display;

  proc greplay nofs tc=&goutemp igout=&goutemp gout=&gout;

    tdef grid des="&nvar. x &nvar."

    %let panel = 0;
    %do row = 1 %to &nvar;

      %let lowerY = %sysevalf (100 - &topGap - &row*&vpct - (&row-1)*&vgap);
      %let upperY = %sysevalf (&lowerY + &vpct);

      %let lowerY = %sysfunc (round(&lowerY,0.01));
      %let upperY = %sysfunc (round(&upperY,0.01));

      %do col = 1 %to &nvar;
        %let lowerX = %sysevalf (0 + (&col-1)*(&hpct+&hgap));
        %let upperX = %sysevalf (&lowerX + &hpct);

        %let lowerX = %sysfunc (round(&lowerX,0.01));
        %let upperX = %sysfunc (round(&upperX,0.01));

        %let panel = %sysevalf (1 + &panel);

        &panel / llx=&lowerX lly=&lowerY
                 ulx=&lowerX uly=&upperY
                 urx=&upperX ury=&upperY
                 lrx=&upperX lry=&lowerY
                 %if %length(&border) %then
                 color=&border
                 ;
    %end;
    %end;
        0 / llx=0 lly=0 ulx=0 uly=100 urx=100 ury=100 lrx=100 lry=0
    ;
    template grid;
    treplay
    %let panel = 0;
    %do row = 1 %to &nvar;
    %do col = 1 %to &nvar;
      %let panel = %sysevalf (1 + &panel);
      %if &row=&col
        %then &panel "_&row.";
        %else &panel "_&row._&col.";
    %end;
    %end;
    %if (&honorTitles = 1) %then %do;
    0 "BG"
    %end;
    name="&name" ;
  run;
  quit;

%mend;

Sample code

options nosymbolgen;

options source mprint;

%let pi = %sysfunc (constant(PI));

data phony;
  n = 400;
  do x = 1 to n;
    a = sin (x/n*2*&pi);
    b = sin (x/n*4*&pi*x/n);
    c = cos (x/n*4*&pi);
    d = cos (x/n*2*&pi);
    e = sqrt(x);
    f = log(x);
    g = exp(x/n*2);
    h = sin(x/n*8*&pi)/(x/(n/4));
    i = ranuni(42)*2-1;
    j = x;
    output;
  end;
  drop n;
run;

ods listing ;

goptions ftext=Helvetica;
goptions ftext="Comic Sans MS";

goptions target=gif;
goptions device=gif;

goptions gsfname=gout;
filename gout "\\extreme\macros\scattermatrix.gif";

title h=7.5pct "Sample of Scatter Matrix";
footnote h=3.75pct j=r "http://www.devenezia.com/downloads/sas/macros/index.php?m=scattermatrix";

%scatterMatrix (
    data=phony
  , vars=A B C D E /*F G H I J*/
  , gout=scattered
  , name=showers
  , symvalue=point
  , bottomGap=4
  , forcesize=1
  , hsize=6.3
  , vsize=6.3
  , hgap=1
  , vgap=1
  , plotOptions = NOFRAME NOAXIS
);

options noxwait noxsync;

x "start %sysfunc(pathname(gout))";