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

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

 

genemroz_0-1617467587999.png

/* 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;
1 ACCEPTED SOLUTION

Accepted Solutions
GraphGuy
Meteorite | Level 14

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;

 

anno_rect.png

 

View solution in original post

7 REPLIES 7
ballardw
Super User

From the documentation:

  • DATAVALUE
    Note: 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.

 

genemroz
Quartz | Level 8

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

genemroz_0-1617549177053.png



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
Meteorite | Level 14
Your HEATMAP axes are discrete. So, XC1 and YC1 have to be character strings.
Since DRAWSPACE is DATAVALUE, maybe the WIDTH and HEIGHT type are not matching.

Another way to do this is to use the POLYGON statement. This can draw any polygon from the same data set using numeric or discrete variables. Another benefit is it can be layered with the other statements and referenced in the legend.

https://blogs.sas.com/content/graphicallyspeaking/2013/12/24/new-polygon-plot/
genemroz
Quartz | Level 8

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

GraphGuy
Meteorite | Level 14

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;

 

anno_rect.png

 

genemroz
Quartz | Level 8
Robert's solution works perfectly. Thanks for helping out!

(Although I'd still like to know how to do this with %sgrectangle)

Regards,

Gene
GraphGuy
Meteorite | Level 14

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).

SAS INNOVATE 2024

Innovate_SAS_Blue.png

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. 

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.

Get the $99 certification deal.jpg

 

 

Back in the Classroom!

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

View all other training opportunities.

Discussion stats
  • 7 replies
  • 631 views
  • 2 likes
  • 4 in conversation