I have searched all over looking for map legend formatting but can't find the answer to my problem. Does SAS have a feature to display legend as a group as indicated below? enter image description here
Thank you
The LEGEND
statement does not have options that allow you to draw the 'desired' legend you have shown (named grouped range categories).
You would have to use some data preprocessing and annotate
data to draw the desired legend.
Consider this sample code that uses gmap
to draw a choro
map of simulated walked paths across a grid. The legend of the map is of the 'doable' nature. A choro
map legend for a numeric response variable will list a value range next to each ranges boxed color. A custom format is used in a PUT
function call to map a numeric response variable to it's realized categorical value. The categorical variable is type string and choro
map legend will list only the value.
%let H_MAX = 88;
%let V_MAX = 50;
%let C_MAX = 4250;
%let P_MAX = 1250;
%let H_CYCLE = 1.5;
%let H_JITTER = 5;
%let V_JITTER = 8;
%let PI = CONSTANT('PI');
%let PI2 = (2 * &PI);
%let PI2K = (2 * &PI * &H_CYCLE);
%let PIK = (&PI * &H_CYCLE);
data grid;
do v = 0 to &V_MAX-1;
do h = 0 to &H_MAX-1;
id + 1;
* data for clockwise edges of a unit square;
segment = 1;
x = h ; y = v ; output;
x = h ; y = v+1; output;
x = h+1; y = v+1; output;
x = h+1; y = v ; output;
end;
end;
stop;
run;
data paths (keep=id pid stepid ix p x y v h type weight);
type = 'S'; weight = 1;
do _n_ = 1 to &P_MAX;
pid + 1;
do ix = 0 to &H_MAX-1;
p = ix + &H_JITTER * ranuni(123) - &H_JITTER / 2;
x = p * &PI2 * &H_CYCLE / &H_MAX;
y = &V_MAX / 2 + &V_MAX / 2.5 * sin ( x );
y = y + &V_JITTER * ranuni(123) - &V_JITTER / 2;
v = floor ( y ) ;
h = floor ( p ) ;
id = v * &H_MAX + h + 1;
stepid + 1;
output;
end;
end;
type = 'C'; weight = 1;
do k = 1 to floor ( &H_CYCLE / 0.5 );
pid + 1;
x = &PI * ( k - 0.5 );
p = x / &PI2 / &H_CYCLE * &H_MAX ;
if mod(k,2) then do;
y = 1 / 3 * &V_MAX;
end;
else do;
y = 2 / 3 * &V_MAX;
end;
do _n_ = 1 to &C_MAX;
theta = &pi2 * ranuni(123) ;
theta = _n_ * &pi2 / &C_MAX ;
dx = &V_MAX / 6 * cos(theta) * ranuni(123);
dy = &V_MAX / 6 * sin(theta) * ranuni(123);
v = floor ( y + dy + ranuni(123) * &V_JITTER - &V_JITTER / 2) ;
h = floor ( p + dx + ranuni(123) * &H_JITTER - &H_JITTER / 2) ;
id = v * &H_MAX + h + 1;
stepid + 1;
output;
end;
end;
type = 'L'; weight = 250;
do k = 1 to floor ( &H_CYCLE / 0.5 );
pid + 1;
x = &PI * ( k - 0.5 );
p = x / &PI2 / &H_CYCLE * &H_MAX ;
if mod(k,2) then do;
y = 1 / 3 * &V_MAX;
dy = 1;
steps = &V_MAX * 5 / 6 - y;
end;
else do;
y = 2 / 3 * &V_MAX;
dy = -1;
steps = y - &V_MAX * 1 / 6;
end;
do _n_ = 0 to steps;
y + dy;
v = floor ( y ) ;
h = floor ( p ) ;
id = v * &H_MAX + h + 1;
stepid + 1;
output;
end;
end;
* every id draws the grid;
type = '*'; weight=1;
pid + 1;
do id = 1 to &H_MAX * &V_MAX;
output;
end;
format pid stepid id 6.;
run;
proc freq noprint data=paths;
table id / out=stepsfreq (keep=id count);
weight weight;
run;
proc format;
value step_count_category
1 = 'None'
2 - 5 = 'Fewest'
6 - 15 = 'Fewer'
16 - 25 = 'Few'
26 - 35 = 'Lowest'
36 - 45 = 'Low'
46 - 60 = 'Moderate Low'
61 - 75 = 'Moderate High'
76 - 125 = 'High'
126 - 175 = 'Higher'
176 - high = 'Highest'
;
value step_count_category_color
1 = 'White'
2 - 5 = 'cx00C200'
6 - 15 = 'cx5BF700'
16 - 25 = 'cx8CF700'
26 - 35 = 'cxBAF700'
36 - 45 = 'cxE0F500'
46 - 60 = 'cxF7DF00'
61 - 75 = 'cxFCB100'
76 - 125 = 'cxFC8200'
126 - 175 = 'cxFA4F00'
176 -high = 'cxCC0000'
;
run;
proc format cntlout=stepsfmt lib=work;
select step_count_category;
run;
data steps;
set stepsfreq;
count_category = put(count,step_count_category.);
run;
proc sql noprint;
select quote(trim(cats(label)))
into :order_list
separated by ' '
from stepsfmt
order by input(strip(start),best12.) descending
;
select put(input(strip(start),best12.),step_count_category_color.)
into :color_list
separated by ' '
from stepsfmt
order by put(input(strip(start),best12.),step_count_category.)
;
quit;
%put NOTE: &=order_list;
%put NOTE: &=color_list;
goptions reset=all;
legend1 label=("Steps")
position = (left middle)
across = 1
cframe = cxf7f7f7
order = (&order_list)
;
ods _all_ close;
ods listing;
options gstyle;
goptions colors = (&color_list) ;
proc gmap map=grid data=steps(keep=id count_category);
id id;
choro count_category /
legend = legend1
coutline = gray
;
run;
quit;