I created a map using gmap. I need to apply colors to different regions using a standard color scale. I tried to convert the scales using both %rgb and %cmyk macros to sas color scheme but I get totally different colors displayed. Any help?
here is the code for both macros:
%macro rgbconvert (r,g,b);
data _null_;
r = &r;
g = &g;
b = &b;
rgb="CX" || put(r,hex2.) || put(g,hex2.) || put(b,hex2.);
put rgb;
run;
%mend rgbconvert;
%rgbconvert (190,27,27);
%rgbconvert (208,34,38);
%rgbconvert (222,54,60);
%rgbconvert (228,93,102);
%rgbconvert (231,111,119);
%rgbconvert (234,129,136);
%rgbconvert (237,147,153);
%rgbconvert (240,165,170);
%rgbconvert (243,183,187);
%rgbconvert (246,201,204);
%rgbconvert (249,219,221);
%rgbconvert (252,237,238);
%rgbconvert (228,241,234);
%rgbconvert (203,228,222);
%rgbconvert (178,215,210);
%rgbconvert (153,202,198);
%rgbconvert (128,189,186);
%rgbconvert (103,176,174);
%rgbconvert (78,163,162);
%rgbconvert (53,150,150);
%rgbconvert (28,137,138);
%rgbconvert (3,124,126);
Am suppose to get colors like deep green, light green, deep red, light red using the listed values. But am getting colors like brown, purple , blue and so on. Is there anything am doing wrong?
Rather than letting the ranges of the user-defined-format control the legend color binning, I prefer to add a variable to the dataset, and specifically assign each observation to a bin (bucket), and then list all those buckets in gmap's midpoints= list (to make sure they all show up in the legend, even if there are no data values in a certain range/bucket). I then use a user-defined-format to make those buckets print in the legend as the range of values they represent. It's a little more manual work, but I think it provides more complete control.
Here's a modification of your code, using my technique:
%let name=map; filename odsout '.'; goptions device=png; goptions border; ODS LISTING CLOSE; ODS HTML path=odsout body="&name..htm" style=htmlblue; goptions gunit=pct ftitle="albany amt/bold" ftext="albany amt" htitle=4.0 htext=2.5; goptions ctext=gray33; proc format; value buckfmt 1 = '130.2 and more' 2 = '120.2 to 130.2' 3 = '105.8 to 120.2' 4 = '97.0 to 105.8' 5 = '80.9 to 97.0' 6 = '70.4 to 80.9' 7 = '60.6 to 70.4' 8 = '50.5 to 60.6' 9 = '48.0 to 50.5' 10 = '40.2 to 48.0' 11 = '34.0 to 40.2' 12 = '27.5 to 34.0' 13 = '21.6 to 27.5' 14 = '16.4 to 21.6' 15 = '12.8 to 16.4' 16 = ' 9.7 to 12.8' 17 = ' 5.8 to 9.7' 18 = ' 3.8 to 5.8' 19 = ' 1.8 to 3.8' 20 = ' 0.5 to 1.8' 21 = ' 0.1 to 0.5' 22 = ' 0.0 to 0.1' ; run; libname here '.'; data modhessen; set here.hessen; if europianstandard>=130.2 then bucket=1; else if europianstandard>=120.2 then bucket=2; else if europianstandard>=105.8 then bucket=3; else if europianstandard>=97.0 then bucket=4; else if europianstandard>=80.9 then bucket=5; else if europianstandard>=70.4 then bucket=6; else if europianstandard>=60.6 then bucket=7; else if europianstandard>=50.5 then bucket=8; else if europianstandard>=48.0 then bucket=9; else if europianstandard>=40.2 then bucket=10; else if europianstandard>=34.0 then bucket=11; else if europianstandard>=27.5 then bucket=12; else if europianstandard>=21.6 then bucket=13; else if europianstandard>=16.4 then bucket=14; else if europianstandard>=12.8 then bucket=15; else if europianstandard>=9.7 then bucket=16; else if europianstandard>=5.8 then bucket=17; else if europianstandard>=3.8 then bucket=18; else if europianstandard>=1.8 then bucket=19; else if europianstandard>=0.5 then bucket=20; else if europianstandard>=0.1 then bucket=21; else if europianstandard>=0.0 then bucket=22; else bucket=.; run; pattern1 value=solid color='CXBF1C1C'; ****red0 redbrown****; pattern2 value=solid color='CXD02226'; ****red1****; pattern3 value=solid color='CXDE363C'; ****red2****; pattern4 value=solid color='CXE45D66'; ****red3****; pattern5 value=solid color='CXE76F77'; ****red4****; pattern6 value=solid color='CXEA8188'; ****red5****; pattern7 value=solid color='CXED9399'; ****red6****; pattern8 value=solid color='CXF0A5AA'; ****red7****; pattern9 value=solid color='CXF3B7BB'; ****lightred8****; pattern10 value=solid color='CXF6C9CC'; ****lightred9****; pattern11 value=solid color='CXF9DBDD'; ****lightred10****; pattern12 value=solid color='CXFCEDEE'; ****palered11****; pattern13 value=solid color='CXE4F1EA'; ****palegreen10****; pattern14 value=solid color='CXCBE4DE'; ****lightgreen9****; pattern15 value=solid color='CXB2D7D2'; ****lightgreen8****; pattern16 value=solid color='CX99C9C7'; ****green7****; pattern17 value=solid color='CX80BDBA'; ****green6****; pattern18 value=solid color='CX67B0AE'; ****green5****; pattern19 value=solid color='CX4EA3A2'; ****green4****; pattern20 value=solid color='CX359696'; ****green3****; pattern21 value=solid color='CX1C898A'; ****green2****; pattern22 value=solid color='CX037C7E'; ****green1****; title1 ls=1.5 "GMap, with custom legend binning"; legend1 label =(f="albany amt/bold" position=top j=c h=12pt "Inzidenzrate") value=(f="albany amt" h=10pt c=black tick=3) across=1 position=(right middle) offset=(-2,3) space=1 mode=reserve shape=bar(.15in,.15in) ; proc gmap map=here.test data=modhessen all; format bucket buckfmt.; ID id; choro bucket/ discrete midpoints = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /* Annotate=maplabelhessen */ legend=legend1 coutline=black cdefault=cxfcfad2 /* areas with no data are light yellow */ name="mychart"; run; quit; ODS HTML CLOSE; ODS LISTING;
Since you don't say where the colors will be applied, let me just point out that if you want the geographic regions (like a state) to have a certain color, you need to produce PATTERN statements that contains the colors you want. An example is here:
If you want colors that are not a specific color name in SAS (like "green" is a specific color name in SAS), you can specify the colors in the RGB hexadecimal scale as
PATTERN COLOR=CXBB5592;
PATTERN2 COLOR=CXAA7700;
etc
So you would have to convert the RGB values to the CX scale in SAS, which you seem to be doing in your code (I didn't test it to determine if your code was doing it correctly)
Also, if you want a smooth gradient of colors, there is the %COLORSCALE macro to produce this gradient
http://support.sas.com/kb/48/480.html
Thanks for your reply, I could solve the issue myself. It was a mistake I made by placing the goptions reset=all below the Pattern statement. This was always resetting the color to the default color, that was why it wasn't worrking.
My next problem now is how do I assign ranges for each of this patterns, like pattern 1 v=s c=green; for ranges between 10.5 and 17.6
I used format to assign them but it seems not to work properly
I used format to assign them but it seems not to work properly
You can't say things like "not to work properly" without giving details, because if that's all you say, we can't help. Show us the SASLOG. Explain why it didn't work.
Hi, here is a sample data. I wish to assign the following formats to the colors listed in the pattern statements. But if I run my program the values are assigned wrongly. Is there any thing I need to add to my code?
proc format;
value class
130.2 - high= '130.2 and more'
120.2 - 130.2= '120.2 to 130.2'
105.8 - 120.2= '105.8 to 120.2'
97.0 - 105.8= '97.0 to 105.8'
80.9 - 97.0 = '80.9 to 97.0'
70.4 - 80.9= '70.4 to 80.9'
60.6 - 70.4= '60.6 to 70.4'
50.5 - 60.6= '50.5 to 60.6'
48.0 - 50.5= '48.0 to 50.5'
40.2 - 48.0= '40.2 to 48.0'
34.0 - 40.2= '34.0 to 40.2'
27.5 - 34.0= '27.5 to 34.0'
21.6 - 27.5= '21.6 to 27.5'
16.4 - 21.6= '16.4 to 21.6'
12.8 - 16.4= '12.8 to 16.4'
9.7 - 12.8= ' 9.7 to 12.8'
5.8 - 9.7= ' 5.8 to 9.7'
3.8 - 5.8= ' 3.8 to 5.8'
1.8 - 3.8= ' 1.8 to 3.8'
0.5 - 1.8= ' 0.5 to 1.8'
0.1 - 0.5= ' 0.1 to 0.5'
0.0 - 0.1= ' 0.0 to 0.1'
;
run;
pattern1 value=solid color='CXBF1C1C'; ****red0 redbrown****;
pattern2 value=solid color='CXD02226'; ****red1****;
pattern3 value=solid color='CXDE363C'; ****red2****;
pattern4 value=solid color='CXE45D66'; ****red3****;
pattern5 value=solid color='CXE76F77'; ****red4****;
pattern6 value=solid color='CXEA8188'; ****red5****;
pattern7 value=solid color='CXED9399'; ****red6****;
pattern8 value=solid color='CXF0A5AA'; ****red7****;
pattern9 value=solid color='CXF3B7BB'; ****lightred8****;
pattern10 value=solid color='CXF6C9CC'; ****lightred9****;
pattern11 value=solid color='CXF9DBDD'; ****lightred10****;
pattern12 value=solid color='CXFCEDEE'; ****palered11****;
pattern13 value=solid color='CXE4F1EA'; ****palegreen10****;
pattern14 value=solid color='CXCBE4DE'; ****lightgreen9****;
pattern15 value=solid color='CXB2D7D2'; ****lightgreen8****;
pattern16 value=solid color='CX99C9C7'; ****green7****;
pattern17 value=solid color='CX80BDBA'; ****green6****;
pattern18 value=solid color='CX67B0AE'; ****green5****;
pattern19 value=solid color='CX4EA3A2'; ****green4****;
pattern20 value=solid color='CX359696'; ****green3****;
pattern21 value=solid color='CX1C898A'; ****green2****;
pattern22 value=solid color='CX037C7E'; ****green1****;
legend1 label =("Inzidenzrate" position=top h=12pt)
value=(h=10pt c=black tick=3 f=Arial)
across=1
position= (right middle)
offset=(-2,2.5)cm
space=1
mode=reserve
;
proc gmap map=test
data=hessen gout=gfout;
ID id ;
format europianstandard class.;
choro europianstandard/ discrete
name="mychart"
Annotate=maplabelhessen
legend= legend1
coutline= black
xsize=7.4 cm
ysize=10 cm
;
run;
title "";
quit;
the values are assigned wrongly.
Details are needed. What is wrong? State clearly what you think should happen, and what does happen.
What happens if you take DISCRETE out of the CHORO statement?
Hello PaigeMiller,
Thanks for your reply, there is a column called europeanstandard in the dataset I sent with some values. The map regions should be coloured depending on this values. This ranges is what I have defined in the proc format. The corresponding colors to be assigned are what I defined in the pattern Statement, that means : pattern1 should be assigned color CXBF1C1C when the range of europeanstandard is between "130.2 - high" and this should be labelled as "130.2 and more" on legend 1 etc.
If I run the program it assigns just red colors although some values which are in the dataset lie in the range where the color should be green. I dont understand why.
Is there any way to find out which format is been assign which color?
I hope you now understand what I mean
pattern1='130.2 and more'
pattern2='120.2 to 130.2'
pattern3='105.8 to 120.2'
pattern4='97.0 to 105.8'
pattern5='80.9 to 97.0'
pattern6='70.4 to 80.9'
and so on
Since I can't download your SAS data sets (my company doesn't allow that), it's not clear to me what the problem is.
What is one of the values that is assigned to red when it should be green?
UPDATE: Disregard this request, I think the answer is in my next post
If your data sets are not too big, you can post them as SAS code, where a datastep reads in the values.
I mean I need something similar to attrmap in sg plot to assign formats and colors to regions in my map (using proc gmap)
Rather than letting the ranges of the user-defined-format control the legend color binning, I prefer to add a variable to the dataset, and specifically assign each observation to a bin (bucket), and then list all those buckets in gmap's midpoints= list (to make sure they all show up in the legend, even if there are no data values in a certain range/bucket). I then use a user-defined-format to make those buckets print in the legend as the range of values they represent. It's a little more manual work, but I think it provides more complete control.
Here's a modification of your code, using my technique:
%let name=map; filename odsout '.'; goptions device=png; goptions border; ODS LISTING CLOSE; ODS HTML path=odsout body="&name..htm" style=htmlblue; goptions gunit=pct ftitle="albany amt/bold" ftext="albany amt" htitle=4.0 htext=2.5; goptions ctext=gray33; proc format; value buckfmt 1 = '130.2 and more' 2 = '120.2 to 130.2' 3 = '105.8 to 120.2' 4 = '97.0 to 105.8' 5 = '80.9 to 97.0' 6 = '70.4 to 80.9' 7 = '60.6 to 70.4' 8 = '50.5 to 60.6' 9 = '48.0 to 50.5' 10 = '40.2 to 48.0' 11 = '34.0 to 40.2' 12 = '27.5 to 34.0' 13 = '21.6 to 27.5' 14 = '16.4 to 21.6' 15 = '12.8 to 16.4' 16 = ' 9.7 to 12.8' 17 = ' 5.8 to 9.7' 18 = ' 3.8 to 5.8' 19 = ' 1.8 to 3.8' 20 = ' 0.5 to 1.8' 21 = ' 0.1 to 0.5' 22 = ' 0.0 to 0.1' ; run; libname here '.'; data modhessen; set here.hessen; if europianstandard>=130.2 then bucket=1; else if europianstandard>=120.2 then bucket=2; else if europianstandard>=105.8 then bucket=3; else if europianstandard>=97.0 then bucket=4; else if europianstandard>=80.9 then bucket=5; else if europianstandard>=70.4 then bucket=6; else if europianstandard>=60.6 then bucket=7; else if europianstandard>=50.5 then bucket=8; else if europianstandard>=48.0 then bucket=9; else if europianstandard>=40.2 then bucket=10; else if europianstandard>=34.0 then bucket=11; else if europianstandard>=27.5 then bucket=12; else if europianstandard>=21.6 then bucket=13; else if europianstandard>=16.4 then bucket=14; else if europianstandard>=12.8 then bucket=15; else if europianstandard>=9.7 then bucket=16; else if europianstandard>=5.8 then bucket=17; else if europianstandard>=3.8 then bucket=18; else if europianstandard>=1.8 then bucket=19; else if europianstandard>=0.5 then bucket=20; else if europianstandard>=0.1 then bucket=21; else if europianstandard>=0.0 then bucket=22; else bucket=.; run; pattern1 value=solid color='CXBF1C1C'; ****red0 redbrown****; pattern2 value=solid color='CXD02226'; ****red1****; pattern3 value=solid color='CXDE363C'; ****red2****; pattern4 value=solid color='CXE45D66'; ****red3****; pattern5 value=solid color='CXE76F77'; ****red4****; pattern6 value=solid color='CXEA8188'; ****red5****; pattern7 value=solid color='CXED9399'; ****red6****; pattern8 value=solid color='CXF0A5AA'; ****red7****; pattern9 value=solid color='CXF3B7BB'; ****lightred8****; pattern10 value=solid color='CXF6C9CC'; ****lightred9****; pattern11 value=solid color='CXF9DBDD'; ****lightred10****; pattern12 value=solid color='CXFCEDEE'; ****palered11****; pattern13 value=solid color='CXE4F1EA'; ****palegreen10****; pattern14 value=solid color='CXCBE4DE'; ****lightgreen9****; pattern15 value=solid color='CXB2D7D2'; ****lightgreen8****; pattern16 value=solid color='CX99C9C7'; ****green7****; pattern17 value=solid color='CX80BDBA'; ****green6****; pattern18 value=solid color='CX67B0AE'; ****green5****; pattern19 value=solid color='CX4EA3A2'; ****green4****; pattern20 value=solid color='CX359696'; ****green3****; pattern21 value=solid color='CX1C898A'; ****green2****; pattern22 value=solid color='CX037C7E'; ****green1****; title1 ls=1.5 "GMap, with custom legend binning"; legend1 label =(f="albany amt/bold" position=top j=c h=12pt "Inzidenzrate") value=(f="albany amt" h=10pt c=black tick=3) across=1 position=(right middle) offset=(-2,3) space=1 mode=reserve shape=bar(.15in,.15in) ; proc gmap map=here.test data=modhessen all; format bucket buckfmt.; ID id; choro bucket/ discrete midpoints = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /* Annotate=maplabelhessen */ legend=legend1 coutline=black cdefault=cxfcfad2 /* areas with no data are light yellow */ name="mychart"; run; quit; ODS HTML CLOSE; ODS LISTING;
Hello Robert,
Thanks a lot for the help and detailed explanation. I am very grateful for that. Since am out of office. I will try that on Monday morning and give you a feedback.
Hi Robert,
once again thanks for the help. I tried the code this morning. It worked fine with the colors. My only problem is that the legend can not be displayed. The warning says : There is no enough room for legend to be displayed. The legend has been suppressed. I tried to reduce the font sizes but without any success. Is there any thing I can do here?
Hi Rober,
I could solve the problem myself by adding origin=(78,18) to my legend statement. It works perfectly. Am very grateful
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.