BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Cruise
Ammonite | Level 13

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?  

SAS proc gmap.jpg

 

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;

 

1 ACCEPTED SOLUTION

Accepted Solutions
GraphGuy
Meteorite | Level 14

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;

 

korea_trick_map.png

View solution in original post

4 REPLIES 4
Cruise
Ammonite | Level 13

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 

proc gremove.png

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;,  

 

 

ballardw
Super User

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.

GraphGuy
Meteorite | Level 14

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;

 

korea_trick_map.png

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 6327 views
  • 3 likes
  • 4 in conversation