Hello folks,
I was making bubble plots following the examples on this webpage but ran into a simple question of how to adjust the color of the legend. My SAS code is as follows:
proc template;
define statgraph bplot2;
begingraph / designheight=480 designwidth=640;
entrytitle 'test';
layout overlay/
xaxisopts=(display=(label ticks tickvalues line) label='Percentage change in caseload' griddisplay=on
linearopts=(viewmin=-2 viewmax=6) offsetmin=0 offsetmax=0.1)
yaxisopts=(display=(label ticks tickvalues line) label='Percentage change in per capita' griddisplay=on
linearopts=(viewmin=-2 viewmax=6) offsetmin=0 offsetmax=0.1);
bubbleplot x=percentage_change_caseload y=percentage_change_percap size=eval(abs(percentage_change_total))/
bubbleradiusmin=0
group=eval(ifc(percentage_change_total<0, 'Negative', 'Positive'))
dataskin=matte name="bubble"
datalabelattrs=(size=8) datalabel=svscd;
discretelegend "bubble"/ title="% change of total" pad=5;
endlayout;
entryfootnote halign=left 'Bubble size represents total % change';
endgraph;
end;
run;
proc sgrender data=gp_2 template=bplot2; run;
Given I have multiple graphs to export and I found the graphs are not consistent with regard to the color in legend with some shows "Positive" being blue, "Negative" being red; others have "Positive" being red, "Negative" being blue. Any help would be greatly appreciated!! Thank you.
No data so can't test. Normally the color assignment is based on the order the value to graph appears in the data. The first group encountered gets the first color. Since you have an IFC assigning the values that order happens can change.
So you could attempt to sort your data before the SGRENDER by the group variable so that the Positive/Negative gets assigned more consistently. Which may be a lot of headache if you try to use the approach with any Series type plot. Or use a DATTRMAP data set to set colors and properties based on the values plotted coupled with a DATTRVAR statement in SGRENDER to indicate which variable to use.
I suspect you may have more luck by assigning the Positive/negative outside of the template, possibly with a FORMAT.
Instead of
group=eval(ifc(percentage_change_total<0, 'Negative', 'Positive'
use
group = percent_change_total
with
Proc format; value posneg low -<0 ='Negative' 0 - high='Positive' ; run;
Then use a Dattrmap data. Format the variable in SGRENDER with the posneg format and use Dattrvar with the variable name.
The DATTRMAP data set would have values of 'Negative' and 'Positive' and set appropriate variables for fill color, marker symbols or what have you. Then you get consistent assignments.
Hi, thanks so much for your reply, I tried your method but it seems the legend is still not consistent. I supposed I have to create a new grouping variable (posgp) to match the original variable percentage_change_pos (which is numeric) and if the variable is < 0 then the posgp= "Negative", else, posgp= "Positive".
Below are my modified codes:
proc template;
define statgraph attrmap1;
begingraph / designheight=480 designwidth=640;
discreteattrmap name='id1' / ignorecase=true;
value 'Negative' / markerattrs=(color=blue symbol=circlefilled);
value 'Positive' / markerattrs=(color=red symbol=circlefilled);
enddiscreteattrmap;
discreteattrvar attrvar=atposgp var=posgp attrmap="id1";
entrytitle '';
layout overlay/
xaxisopts=(display=(label ticks tickvalues line) label='Percentage change in caseload' griddisplay=on
linearopts=(viewmin=-2 viewmax=6) offsetmin=0 offsetmax=0.1)
yaxisopts=(display=(label ticks tickvalues line) label='Percentage change in per capita' griddisplay=on
linearopts=(viewmin=-2 viewmax=6) offsetmin=0 offsetmax=0.1);
bubbleplot x=percentage_change_caseload y=percentage_change_percap size=eval(abs(percentage_change_pos))/
group=atposgp bubbleradiusmin=0
dataskin=matte name='bubble'
datalabelattrs=(size=8) datalabel=svscd;
discretelegend "id1"/ title="% change of pos" pad=5;
endlayout;
entryfootnote halign=left 'Bubble size represents % change in total POS';
endgraph;
end;
run;
proc format;
value grplabel
low -<0 ='Negative'
0 - high='Positive'; run;
proc sgrender data=gp_2 template=attrmap1;
format percentage_change_pos grplabel.; run;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
See how to use one filter for multiple data sources by mapping your data from SAS’ Alexandria McCall.
Find more tutorials on the SAS Users YouTube channel.