Hi, I'm struggling with getting range attirbute maps to work correctly. Mainly been using Sanjay Metange's blog post as base
https://blogs.sas.com/content/graphicallyspeaking/2013/04/14/attributes-map-3-range-attribute-map/
This is done using version 9.4.3.0. Programmed in EG 7.15 HF3.
I get he code in the example to run but when trying with my own data I only get a uniform color..
Example data and my programs are below.
I also have another question. This is actually a data representing a map. I can get equated axis right using the GTL language, but can't find a function other than manipulating height and width when using SGPLOT. Is this right? If so are there any plans of including true equated columns in SGPLOT?
/*Just create some example data*/
Data range;
call streaminit(123);
do x=10 to 30 by 1;
do y=10 to 60 by 2;
u = rand("Uniform");
value= -0.5 + (0.5 - (-0.5))*u;
output;
end;
end;
run;
/*Create the range attribute map*/
data clrresp;
retain id "slope";
length min max $ 5 color altcolor colormodel1 colormodel2 $ 18;
input min $ max $ color $ altcolor $ colormodel1 $ colormodel2 $;
datalines;
_min_ -0.3 . . purple purple
-0.3 -0.15 . . purple blue
-0.15 -0.07 . . blue lightblue
-0.07 0 . . lightblue cxf7f7f7
0 0 white white . .
0 0.07 . . cxf7f7f7 gold
0.07 0.15 . . gold red
0.15 0.3 . . red darkred
0.3 _max_ . . darkred darkred
;
run;
/*Do the plot, not trying to do equated axis*/
proc sgplot data=range
RATTRMAP=clrresp;
scatter x=x y=y /
colorresponse=value
markerattrs=(SYMBOL=SQUAREFILLED SIZE=5PX)
rattrid=slope
;
run;
/*Using equated axis and trying to get the consistent range to work*/
proc template;
define statgraph constrange;
begingraph;
rangeattrvar attrvar=attrvar var=value attrmap='slope';
rangeattrmap name='slope';
range -1 - -0.3 / rangecolormodel=(purple purple);
range -0.3 - -0.15 / rangecolormodel=(purple blue);
range -0.15 - -0.07 / rangecolormodel=(blue lightblue);
range -0.07 - 0 / rangecolormodel=(lightblue cxf7f7f7);
range -0 -0/ rangecolor = white;
range 0 - 0.07 / rangecolormodel=(cxf7f7f7 gold);
range 0.07 - 0.15 / rangecolormodel=(gold red);
range 0.15 - 0.3 / rangecolormodel=(red darkred);
range 0.3 - 1 / rangecolormodel=(darkred darkred);
endrangeattrmap;
* EntryTitle "Parameter = &sumvar, i=&i, j=&j, k=&k" /;
layout Overlayequated / cycleattrs=true
xaxisopts=(display = (ticks tickvalues line ))
yaxisopts=( display=( ticks tickvalues line ))
;
ScatterPlot X='x'n Y='y'n /
colorresponse=attrvar
subpixel=off
primary=true
Markerattrs=( Symbol=SQUAREFILLED size=5 px)
LegendLabel="Y" NAME="Map";
ContinuousLegend "Map"/ title="Lofs variability";* location=inside autoalign=(bottom);
endlayout;
endgraph;
end;
run;
/*Render the graph. result not shown*/
ods graphics on ;
proc sgrender data=range template=constrange;
run;
Hi PaalNavestad,
For markers in scatter plots, use altcolor. In your clrresp data set, try changing variables colormodel1 and colormodel2 to altcolormode1 and altcolormodel2, respectively:
data clrresp;
retain id "slope";
length min max $ 5 color altcolor altcolormodel1 altcolormodel2 $ 18;
input min $ max $ color $ altcolor $ altcolormodel1 $ altcolormodel2 $;
datalines;
_min_ -0.3 . . purple purple
-0.3 -0.15 . . purple blue
-0.15 -0.07 . . blue lightblue
-0.07 0 . . lightblue cxf7f7f7
0 0 white white . .
0 0.07 . . cxf7f7f7 gold
0.07 0.15 . . gold red
0.15 0.3 . . red darkred
0.3 _max_ . . darkred darkred
;
run;
In the rangeattrmap block in your constrange template code, try changing rangecolormodel to rangealtcolormodel:
rangeattrmap name='slope';
range -1 - -0.3 / rangealtcolormodel=(purple purple);
range -0.3 - -0.15 / rangealtcolormodel=(purple blue);
range -0.15 - -0.07 / rangealtcolormodel=(blue lightblue);
range -0.07 - 0 / rangealtcolormodel=(lightblue cxf7f7f7);
range -0 -0/ rangealtcolor = white;
range 0 - 0.07 / rangealtcolormodel=(cxf7f7f7 gold);
range 0.07 - 0.15 / rangealtcolormodel=(gold red);
range 0.15 - 0.3 / rangealtcolormodel=(red darkred);
range 0.3 - 1 / rangealtcolormodel=(darkred darkred);
endrangeattrmap;
With those changes, here is my output from sgplot.
Since you assign no values for COLOR or ALTCOLOR except for the range 0 to 0 what do you expect?
Is this closer to what you expected:
Data range; call streaminit(123); do x=10 to 30 by 1; do y=10 to 60 by 2; u = rand("Uniform"); value= -0.5 + (0.5 - (-0.5))*u; output; end; end; run; /*Create the range attribute map*/ data clrresp; retain id "slope"; length min max $ 5 color altcolor $ 18; input min $ max $ color $ altcolor $ ; datalines; _min_ -0.3 purple purple -0.3 -0.15 purple blue -0.15 -0.07 blue lightblue -0.07 0 lightblue cxf7f7f7 0 0 white white 0 0.07 cxf7f7f7 gold 0.07 0.15 gold red 0.15 0.3 red darkred 0.3 _max_ darkred darkred ; run; /*Do the plot, not trying to do equated axis*/ proc sgplot data=range RATTRMAP=clrresp; scatter x=x y=y / colorresponse=value markerattrs=(SYMBOL=SQUAREFILLED SIZE=5PX) rattrid=slope ; run;
Not completly. This give fixed colors for the ranges and not gradients thorugh the ranges.
This is an example from the SAS documentation
data clrresp; retain id "myid"; length min $ 5 max $ 5; input min $ max $ color $ altcolor $ colormodel1 $ colormodel2 $ colormodel3 $; datalines; _min_ 90 purple purple . . . 90 100 gold gold . . . 100 _max_ . . red orange yellow ; run;
The link is http://documentation.sas.com/?docsetId=grstatproc&docsetTarget=n1fxl54aizx1tjn1nfder5bsqqco.htm&docs...
As can be seen the last range is graduated. This what I relly need in the case.
However I can get further thanks to your help.
Perhaps this is closer:
data clrresp; retain id "slope"; length min max $ 5 color altcolor colormodel1-colormodel7 $ 18; input min $ max $ color $ altcolor $ colormodel1 - colormodel7 $; datalines; _min_ -0.3 purple purple . . . . . . . -0.3 -0.15 purple blue . . . . . . . -0.15 -0.07 blue lightblue . . . . . . . -0.07 0 lightblue cxf7f7f7 . . . . . . . 0 0 white white . . . . . . . 0 0.07 cxf7f7f7 gold . . . . . . . 0.07 0.15 gold red . . . . . . . 0.15 0.3 red darkred . . . . . . . 0.3 .49 darkred darkred . . . . . . . .49 _max_ . . lightpurple blue lightblue cxf7f7f7 gold red darkred ; run; /*Do the plot, not trying to do equated axis*/ ods html style=htmlblue; proc sgplot data=range RATTRMAP=clrresp; scatter x=x y=y / colorresponse=value markerattrs=(SYMBOL=SQUAREFILLED SIZE=5PX) rattrid=slope ; run;
Watch for messages about the min or max values and overlaps.
It seems that certain gaps or overlaps with the _min_ and _max_ or the values on those two rows in the data the proc may fall back to a twocolor or threecolor ramp.
Your original .3 _max_ with the same color for both values of the two colors was setting the uniform color as there was no "gradient" to build between darkred and darkred.
Thanks Ballard.
There is som strangness in the numbers I start to think. if you override max and min it reverts to a two color, Three color ramp. However this is not the case here as it emphazies only one color. I'm testing With rounded numbers but I'm not finished yet.
Thanks for Your reply.
I've think I found the bug in this now.
It seems as if the Range attriute map is not working for scatter plots. Changing to a bubble plot and it works.
Here is the modified code. Running this it does attribute the changes.
Would be really interesting to hear from some of the SAS graph experts why this do not work for scatterplot. In my real world example this is only a temporar workaround.
Data range;
call streaminit(123);
do x=10 to 30 by 1;
do y=10 to 60 by 2;
u = rand("Uniform");
value= -0.5 + (0.5 - (-0.5))*u;
size=4;
output;
end;
end;
run;
/*Create the range attribute map*/
data clrresp;
retain id "slope";
length min max $ 5 color altcolor colormodel1 colormodel2 $ 18;
input min $ max $ color $ altcolor $ colormodel1 $ colormodel2 $;
datalines;
_min_ -0.3 . . purple purple
-0.3 -0.15 . . purple blue
-0.15 -0.07 . . blue lightblue
-0.07 0 . . lightblue cxf7f7f7
0 0 white white . .
0 0.07 . . cxf7f7f7 gold
0.07 0.15 . . gold red
0.15 0.3 . . red darkred
0.3 _max_ . . darkred darkred
;
run;
/*Do the plot, not trying to do equated axis*/
proc sgplot data=range
RATTRMAP=clrresp;
bubble x=x y=y size=size /
colorresponse=value
rattrid=slope
;
run;
Hi PaalNavestad,
For markers in scatter plots, use altcolor. In your clrresp data set, try changing variables colormodel1 and colormodel2 to altcolormode1 and altcolormodel2, respectively:
data clrresp;
retain id "slope";
length min max $ 5 color altcolor altcolormodel1 altcolormodel2 $ 18;
input min $ max $ color $ altcolor $ altcolormodel1 $ altcolormodel2 $;
datalines;
_min_ -0.3 . . purple purple
-0.3 -0.15 . . purple blue
-0.15 -0.07 . . blue lightblue
-0.07 0 . . lightblue cxf7f7f7
0 0 white white . .
0 0.07 . . cxf7f7f7 gold
0.07 0.15 . . gold red
0.15 0.3 . . red darkred
0.3 _max_ . . darkred darkred
;
run;
In the rangeattrmap block in your constrange template code, try changing rangecolormodel to rangealtcolormodel:
rangeattrmap name='slope';
range -1 - -0.3 / rangealtcolormodel=(purple purple);
range -0.3 - -0.15 / rangealtcolormodel=(purple blue);
range -0.15 - -0.07 / rangealtcolormodel=(blue lightblue);
range -0.07 - 0 / rangealtcolormodel=(lightblue cxf7f7f7);
range -0 -0/ rangealtcolor = white;
range 0 - 0.07 / rangealtcolormodel=(cxf7f7f7 gold);
range 0.07 - 0.15 / rangealtcolormodel=(gold red);
range 0.15 - 0.3 / rangealtcolormodel=(red darkred);
range 0.3 - 1 / rangealtcolormodel=(darkred darkred);
endrangeattrmap;
With those changes, here is my output from sgplot.
Thanks sdengland, I did not find any clue about this in the documentation. Is there any reason for scatter and bubble/countour working differently?. This makes it kind of hard to switch between different plots.
I'm using this in a proxy for a map. Seems like I have to switch to using a custom map set. Are there any pointers to have to control the colors in maps in the same way?
Thanks again.
The reason we have COLOR (for fills) and ALTCOLOR (for lines and markers), is that, generally, the same color does not work well for both types of plotting primitives. Lines and markers have less surface area, so you usually need a more contrasted color for them to stand out than you do for filled areas. By having both a COLOR and an ALTCOLOR specified in your map, you can create different, but related, colors for all situations where you might use the map.
Hope this helps!
Dan
Thanks Dan, I can see the point. However I struggled hard to understand this and there are really no good examples or blog posts, at least that I have found that explains this. In the real word example I was working on in this case I used a scatterplot to simulate a map so the markers would be large and needed a fill color type thonking. And squares worked better than circles so I did not think about using a bubble plot in the beginning.
It is also a bit confusing that when you do not specify a dedicated range, fills and markers work the same way.
I would recommend that a good example/ blog post is made.
Hi PaalNavestad,
Thanks for your feedback. We will provide more information about this behavior in our documentation for the next release of SAS.
Best regards,
Steve
Thanks Steve. What I find most useful is examples or blog posts. Graphically Speaking has been a really great tool for me in understanding and as an inspiration.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.