Hi Folks:
I'm trying to let my blocks stand out on the area background (beige right now) while showing the outside border (all regional borders are shown in grey now) of the map without regional borders inside the map. How to only show the country border? I'm also curious if blue blocks on the beige making sense to you?
Thanks so much for your time and thoughts on this.
options orientation=landscape;
legend1 position=(bottom right inside) across=1 mode=share
label=("Number of cases" position=top j=c) offset=(-1.5cm,1.5cm);
pattern5 v=msolid c=beige;
proc gmap data=mydata map=mapsgfk.south_korea;
id id;
/*area total/nolegend;*/
block N_cases/legend=legend1 coutline=grey;
format N_cases comma5.;
run;
quit;
ods pdf close;
This is indeed a tough question ...
With a flat/choro map, you could plot your data for each id (small area), and then overlay the borders for the id2 areas (which you determined using gremove) by annotating lines/polygons...
But since you're using a 3d block map, there's not a good way to annotate those borders on top of the map, but 'behind' the bars. And actually, since the 3d block map has a bit of a tilt to it, I don't think annotated lines/polygons will line up correctly with the map anyway.
So, I had to come up with a solution not using annotate...
I used the gremoved id1 map as the visible map, and then also combined that with a map that just consisted of 1 x/y point for each small id area. The data matching the id areas will draw the block/bars, and the background of the map will be drawn by the 'all' option and the cdefault color. There's a lot of "trickery" and "slight of hand" going on in this technique, but it's the only way I can think of to get the map you're wanting...
/* create a map containing 1-point at the center of each id */
/* these will not be visible map areas - you will only see the block bars */
%annomac;
%centroid(mapsgfk.south_korea,korea_id,id,segonly=1);
/* create a map of the id1 boundaries */
proc gremove data=mapsgfk.south_korea out=korea_id1;
by id1;
id id;
run;
/* assign a fake id for each id1 area */
data korea_id1;
length id $50;
set korea_id1;
id=trim(left(id1))||'xxx';
run;
/* combine the 2 maps */
data korea; set korea_id korea_id1 ;
run;
/* create some fake data, just for the demonstration */
proc sql noprint;
create table fakedata as
select unique id, ranuni(123)*100 as n_cases
from mapsgfk.south_korea
group by id;
quit; run;
/* plot the combined map, the id1 areas get the cdefault beige, and the id areas get the block bars */
proc gmap data=fakedata map=korea all;
id id;
block n_cases / cdefault=beige nolegend blocksize=1.0;
run;
PROC GREMOVE. Done this once. I found some other sources that should help you do this
Solved: Creating a Region Map from counties across multipl... - SAS Support Communities
SAS Help Center: Example: PROC GREMOVE Removing State Boundaries from U.S. Map
Hi @PhilC
Thanks for the resources. I tried proc gremove however, removing district boundaries from the map data resulted in a loss of data in my outcome that I'm trying to map.
Would you please point out what I'm doing wrong? @GraphGuy
The proc gremove I tried is following.
proc gremove data=mapsgfk.south_korea out=korea;
by id1;
id id;
run;
proc gmap data=mydata map=korea;
id id;
block n_cases/legend=legend1 coutline=grey;
format n_cases comma5.;
run;
quit;
ods pdf close;,
In the past when I needed a custom border to overlay on a map with subregions I created an annotate data set of just that border.
However I had the advantage of not having as complex a border as a coastline or islands.
The basic approach would be to use the map data set generate by proc remove as input to a data step and then create the Draw statements to connect consecutive points (the annotate macros are helpful). You would also need to provide the closing link from the last x,y pair to the first.
Islands would need to have a move between draw statements to complete them. You might consider using the MAPS.Koreasou library data set instead of the MAPSGFK as it is a bit simpler and might be easier to do this.
This is indeed a tough question ...
With a flat/choro map, you could plot your data for each id (small area), and then overlay the borders for the id2 areas (which you determined using gremove) by annotating lines/polygons...
But since you're using a 3d block map, there's not a good way to annotate those borders on top of the map, but 'behind' the bars. And actually, since the 3d block map has a bit of a tilt to it, I don't think annotated lines/polygons will line up correctly with the map anyway.
So, I had to come up with a solution not using annotate...
I used the gremoved id1 map as the visible map, and then also combined that with a map that just consisted of 1 x/y point for each small id area. The data matching the id areas will draw the block/bars, and the background of the map will be drawn by the 'all' option and the cdefault color. There's a lot of "trickery" and "slight of hand" going on in this technique, but it's the only way I can think of to get the map you're wanting...
/* create a map containing 1-point at the center of each id */
/* these will not be visible map areas - you will only see the block bars */
%annomac;
%centroid(mapsgfk.south_korea,korea_id,id,segonly=1);
/* create a map of the id1 boundaries */
proc gremove data=mapsgfk.south_korea out=korea_id1;
by id1;
id id;
run;
/* assign a fake id for each id1 area */
data korea_id1;
length id $50;
set korea_id1;
id=trim(left(id1))||'xxx';
run;
/* combine the 2 maps */
data korea; set korea_id korea_id1 ;
run;
/* create some fake data, just for the demonstration */
proc sql noprint;
create table fakedata as
select unique id, ranuni(123)*100 as n_cases
from mapsgfk.south_korea
group by id;
quit; run;
/* plot the combined map, the id1 areas get the cdefault beige, and the id areas get the block bars */
proc gmap data=fakedata map=korea all;
id id;
block n_cases / cdefault=beige nolegend blocksize=1.0;
run;
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.