I'm trying to use %SGANNO and %SGRECTANGLE to overlay a square centered on the intersection of the reference lines of the following graph. Seems simple enough, but no square appears. Must be something simple I'm overlooking and would greatly appreciate your insights. The code I'm using appears below the graph.
Thanks,
Gene
/* create annotation data set */
%sganno;
data anno;
%SGRECTANGLE(drawspace="datavalue",x1=0,y1=0,width=200,height=200);
output;
run;
/*Create HeatMap*/
ods graphics / reset width=6.4in height=6.4in imagemap;
proc sgplot data=work.optcamer_k_coverage sganno=anno aspect=1;
where tz=80;
title height=12pt "OPTModel Camera Coverage @100km for 200x200km grid at 80km";
heatmap x=Tx y=Ty / name='HeatMap' discretex discretey
colorresponse=k_coverage colormodel=(cxfeebe2 cxfbb4b9 cxf768a1 cxc51b8a cx7a0177)
transparency=0;
gradlegend /title='Number of Cameras';
xaxis label='KM' valuesrotate=vertical grid values=(-300 to 300 by 10);
yaxis label='KM' grid values=(-300 to 300 by 10);
refline "0" / axis=x lineattrs=(thickness=2 color=blue) label
labelattrs=(color=blue);
refline "0" / axis=y lineattrs=(thickness=2 color=blue) label
labelattrs=(color=blue);
run;
I prefer creating my annotate datasets manually, rather than using the macros - that way I know exactly what's going in them! Here's the basic code for how I would do it in your case:
data anno;
length xc1 yc1 $10 function $50;
layer='front';
x1space='datavalue';
y1space='datavalue';
function='polygon';
xc1='-100'; yc1='-100'; output;
function='polycont';
xc1='100'; yc1='-100'; output;
xc1='100'; yc1='100'; output;
xc1='-100'; yc1='100'; output;
run;
From the documentation:
DATAVALUENote: When a DATAVALUE annotation is associated with a discrete axis, the annotation value must be a formatted value on the axis. Use the XC1 or YC1 columns for those values.
So try using XC1 and YC1 instead of X1 and Y1 in the annotate.
Can't test your specific code without data.
Thanks, ballardw, for your reply.
I followed your suggestion but to no avail. Below is the code (including a dummy dataset), the result and the log. Still a puzzle to me why no rectangle appears. Error message indicates missing/invalid value for x or y position but since it's not missing, then it must be invalid but I can't see why/how it can be invalid.
Thanks for taking the time to look at this,
Regards,
Gene
DATA k_coverage;
INPUT TX TY TZ K;
DATALINES;
50 50 80 2
100 100 80 4
150 150 80 6
200 200 80 8
-50 -50 80 10
-100 -100 80 8
-150 -150 80 6
-200 -200 80 4
;
PROC PRINT DATA=k_coverage;
TITLE 'LIST INPUT';
RUN;
/* create annotation data set */
%sganno;
data anno;
%SGRECTANGLE(drawspace="datavalue",xc1=0,yc1=0,width=200,height=200);
output;
run;
/*Create HeatMap*/
ods graphics / reset width=6.4in height=6.4in imagemap;
proc sgplot data=work.k_coverage sganno=anno aspect=1;
where tz=80;
title height=12pt "OPTModel Camera Coverage @100km for 200x200km grid at 80km";
heatmap x=Tx y=Ty / name='HeatMap' discretex discretey
colorresponse=k colormodel=(cxfeebe2 cxfbb4b9 cxf768a1 cxc51b8a cx7a0177)
transparency=0;
gradlegend /title='Number of Cameras';
xaxis label='KM' valuesrotate=vertical grid values=(-300 to 300 by 10);
yaxis label='KM' grid values=(-300 to 300 by 10);
refline "0" / axis=x lineattrs=(thickness=2 color=blue) label
labelattrs=(color=blue);
refline "0" / axis=y lineattrs=(thickness=2 color=blue) label
labelattrs=(color=blue);
run;
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
NOTE: ODS statements in the SAS Studio environment may disable some output features.
73
74
75
76 DATA k_coverage;
77 INPUT TX TY TZ K;
78 DATALINES;
NOTE: The data set WORK.K_COVERAGE has 8 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 779.40k
OS Memory 36008.00k
Timestamp 04/04/2021 03:11:13 PM
Step Count 211 Switch Count 2
Page Faults 0
Page Reclaims 147
Page Swaps 0
Voluntary Context Switches 11
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 264
87 ;
88 PROC PRINT DATA=k_coverage;
89 TITLE 'LIST INPUT';
90 RUN;
NOTE: There were 8 observations read from the data set WORK.K_COVERAGE.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.03 seconds
user cpu time 0.04 seconds
system cpu time 0.01 seconds
memory 2581.93k
OS Memory 36520.00k
Timestamp 04/04/2021 03:11:13 PM
Step Count 212 Switch Count 1
Page Faults 0
Page Reclaims 146
Page Swaps 0
Voluntary Context Switches 7
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 8
91
92 /* create annotation data set */
93 %sganno;
*** SGANNO macros are now available ***
NOTE: SGANNO macros (except SGANNO_HELP) should be used within data step.
Following macros are available
%SGANNO_HELP
%SGARROW
%SGIMAGE
%SGLINE
%SGOVAL
%SGPOLYCONT
%SGPOLYGON
%SGPOLYLINE
%SGRECTANGLE
%SGTEXT
%SGTEXTCONT
Enter %SGANNO_HELP(macroname) for details on each SGANNO macro,
or %SGANNO_HELP(ALL) for details on all SGANNO macros.
94 data anno;
95 %SGRECTANGLE(drawspace="datavalue",xc1=0,yc1=0,width=200,height=200);
96 output;
97 run;
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
95:2 95:2
NOTE: The data set WORK.ANNO has 2 observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 648.34k
OS Memory 36776.00k
Timestamp 04/04/2021 03:11:13 PM
Step Count 213 Switch Count 2
Page Faults 0
Page Reclaims 126
Page Swaps 0
Voluntary Context Switches 15
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 264
98 /*Create HeatMap*/
99 ods graphics / reset width=6.4in height=6.4in imagemap;
100 proc sgplot data=work.k_coverage sganno=anno aspect=1;
101 where tz=80;
102 title height=12pt "OPTModel Camera Coverage @100km for 200x200km grid at 80km";
103 heatmap x=Tx y=Ty / name='HeatMap' discretex discretey
104 colorresponse=k colormodel=(cxfeebe2 cxfbb4b9 cxf768a1 cxc51b8a cx7a0177)
105 transparency=0;
106 gradlegend /title='Number of Cameras';
107 xaxis label='KM' valuesrotate=vertical grid values=(-300 to 300 by 10);
108 yaxis label='KM' grid values=(-300 to 300 by 10);
109 refline "0" / axis=x lineattrs=(thickness=2 color=blue) label
110 labelattrs=(color=blue);
111 refline "0" / axis=y lineattrs=(thickness=2 color=blue) label
112 labelattrs=(color=blue);
113 run;
NOTE: PROCEDURE SGPLOT used (Total process time):
real time 0.40 seconds
user cpu time 0.23 seconds
system cpu time 0.04 seconds
memory 31212.65k
OS Memory 66032.00k
Timestamp 04/04/2021 03:11:14 PM
Step Count 214 Switch Count 2
Page Faults 0
Page Reclaims 8970
Page Swaps 0
Voluntary Context Switches 309
Involuntary Context Switches 1
Block Input Operations 0
Block Output Operations 1528
NOTE: The graph in the PDF(WEB) destination will be rendered as an image due to the use of transparency and continuous legend.
NOTE: Some of the tick values have been thinned.
WARNING: DrawRectangle statement has missing/invalid value for position (X or Y). Draw statement discarded.
WARNING: DrawRectangle statement has missing/invalid value for position (X or Y). Draw statement discarded.
NOTE: Some of the tick values have been thinned.
WARNING: DrawRectangle statement has missing/invalid value for position (X or Y). Draw statement discarded.
WARNING: DrawRectangle statement has missing/invalid value for position (X or Y). Draw statement discarded.
NOTE: Some of the tick values have been thinned.
WARNING: DrawRectangle statement has missing/invalid value for position (X or Y). Draw statement discarded.
WARNING: DrawRectangle statement has missing/invalid value for position (X or Y). Draw statement discarded.
NOTE: There were 8 observations read from the data set WORK.K_COVERAGE.
WHERE tz=80;
114
115
116 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
128
Jay54, thanks for your response. I tried running the code with xc1='0' and yc1='0' but no square (nor any error messages) appeared.
May have to look into POLYGON, but this approach seemed (at first glance) a lot simpler for this particular task.
Thanks,
Gene
I prefer creating my annotate datasets manually, rather than using the macros - that way I know exactly what's going in them! Here's the basic code for how I would do it in your case:
data anno;
length xc1 yc1 $10 function $50;
layer='front';
x1space='datavalue';
y1space='datavalue';
function='polygon';
xc1='-100'; yc1='-100'; output;
function='polycont';
xc1='100'; yc1='-100'; output;
xc1='100'; yc1='100'; output;
xc1='-100'; yc1='100'; output;
run;
I haven't dug into the code to verify, but I suspect the %sgrectangle macro has difficulty taking numeric coordinates, and applying numeric offsets ... and then producing an annotate dataset that has a character version of those numeric coordinates (because this particular kind of graph requires character values).
Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.
If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website.
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.