I am trying to keep the "5-19" range on my legend but I do not have any data that falls in it so it gets removed from my map. Any suggestions?
legend1 across=1 origin=(65,10)pct mode=share shape=bar(2,2)pct label=(h=14pt position=top "Count")
value=(h=12pt);
proc format;
value comm
1-4 = '1 - 4'
5-19 = '5 - 19'
20-49 = '20 - 49'
50-high = '50 - 885';
title "XXXXXXXXXXXXXXXX";
footnote j=r 'XXXXXXXXXXXXXXX';
proc gmap
data=A1
map=NJ all annotate=P;
id COUNTY;
choro count / discrete legend=legend1 coutline=black anno=anno1;
format count comm.;
run;
quit;
One approach is to use an annotate data set and the NOLEGEND option.
Use the annotate macros to simplify code. This one places a legend label above a group of circles of different color and size. You probably would want %BAR to indicate just a color region. If you already have an annotate set you can either append this type of data to your existing annotate set.
%annomac;
Data legend;
length function style color $ 30 position $ 1 text $ 30 ;
retain when 'a';
%system (3,3,3); /*uses percent of graph area for coordinates*/
/* move the title for the legend down instead of moving the rest up
in quick adjustment to remove the NONE*/
%LABEL(42, 79.5, 'Home Visiting Programs' ,BLACK, 0, 0, 2.0, swissB, 6);
%slice(50, 76, 0, 360, .6 ,H10E66AA, SOLID, NONE );
%LABEL(51, 76.8, ' Parents as Teachers (PAT)' ,BLACK, 0, 0, 2.0, swissl, 6);
%slice(50, 73, 0, 360, .6,orange, SOLID, NONE );
%LABEL(51, 73.6, ' Early Head Start (EHS)' ,BLACK, 0, 0, 2.0, swissl, 6);
%slice(50, 70, 0, 360,1.1,MEDIUMVIOLETRED, SOLID, NONE );
%LABEL(51, 70.6, ' EHS & PAT' ,BLACK, 0, 0, 2.0, swissl, 6);
run;
hi ... here's something that I have used for similar problems (it's looks LONG, but I had to create a NJ response data set ... that's data that you already have so all you have to do for the response data set is step #2)
#1 add an observation to the map data set with a non-NJ county number (I used 999)
#2 add an observation to the response data with the same county number and a value to be mapped that falls in the missing range (5-19)
#3 you get a map with only 3 colors, but a legend with 4 entries
* New Jersey map data set;
proc gproject data=maps.counties out=nj;
id county;
where state eq 34 and density lt 6;
run;
* response data set with one observation per county;
proc sql;
create table njfake as select distinct county from nj;
quit;
* add one observation to the map data set ... a point with county = 999;
data nj;
set nj end=last;
output;
if last then do;
county = 999;
output;
end;
run;
* add some data to the response data set ... no observations in the range 5 to 19;
data njfake;
array x(3) _temporary_ (3 25 75);
set njfake;
dummy = x(rantbl(999,.33,.33));
run;
* add one observation to the response data set ... county = 999, dummy in the range 5-19;
data njfake;
set njfake end=last;
output;
if last then do;
county = 999;
dummy = 5;
output;
end;
run;
proc format;
value comm 1-4 = '1 - 4' 5-19 = '5 - 19' 20-49 = '20 - 49' 50-high = '50 - 885';
run;
goptions reset=all ftext='calibri' htext=2 gunit=pct;
legend1 mode=share origin=(5,45)pct shape=bar(3,4)pct across=1 label=(position=top '!!! HOORAY !!!');
title h=4 'THREE COLORS IN MAP, FOUR COLORS IN LEGEND' ls=2;
* draw the map ... legend has four entries, map has three colors (you cannot see county 999);
proc gmap data=njfake map=nj all;
id county;
choro dummy / discrete legend=legend1 coutline=black;
format dummy comm.;
run;
quit;
One of the cool things about gmap is that it has a 'midpoints=' option, and you can specify the midpoints you want to appear in the legend (even if those values aren't in ever set of data you might plot on the map). This way, as you are desiring, all the colors get shown in the legend, and therefore all the maps you create will consistently map the same colors to the same values.
In this case you're using a user-defined format (UDF) to map ranges of values to legend colors. I had never tried using this with midpoints= before, but it appears to work ... Just specify a 'midpoint' that happens to be somewhere in each of the UDF ranges, and they will all show up in the legend.
I've written a little example, with (random) data, to demonstrate (try it with & without the midpoints= to see the difference):
data NJ; set maps.uscounty (where=(state=stfips('NJ'));
run;
proc sql;
create table A1 as select unique county from NJ;
quit; run;
data A1; set A1;
count=round(ranuni(556)*49);
if count>=5 and count<=19 then count=800;
run;
legend1 across=1 origin=(65,10)pct mode=share shape=bar(2,2)pct
label=(h=14pt position=top "Count") value=(h=12pt);
proc format;
value comm
1-4 = '1 - 4'
5-19 = '5 - 19'
20-49 = '20 - 49'
50-high = '50 - 885';
proc gmap
data=A1
map=NJ all;
id COUNTY;
choro count / discrete
midpoints = 1 5 20 50
legend=legend1 coutline=black;
format count comm.;
run;
quit;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.