BookmarkSubscribeRSS Feed
chiaholee
Calcite | Level 5

Hi, I would like to add arrows to show "improved/worsened" in the waterfall plot output like the screenshot below.  The separation point of the red/green arrows is based on the y-axis line 0.0. I can use annotation to get it shown from PROC SGPLOT on the first page (the SAS code is provided). However, because the program will generate multiple pages, each page represents a different item with different y-axis range.  The position of 0.0 line on each page will change/shift, therefore a fixed position of the arrows (from the annotation below) won't work. Would you please provide some suggestions/solutions on this issue to help me get this resolved?  Many thanks. (or is there a way to display these red/green arrows inside the plot and does not mess up the plot itself?)

chiaholee_0-1709842261137.png

data anno1;
   length textcolor $40;
   drawspace ="GRAPHPERCENT";
   function="text";
   ANCHOR= "TOP";
   rotate=90;
   label = 'Worsened';
   x1=98; y1=70; 
   textcolor ="RED";
   output;
   x1=98; y1=88; 
   label = 'Improved';
   textcolor ="GREEN";
   output;
run;
 
data anno2;
   drawspace ="GRAPHPERCENT";
   function ='ARROW';
   SHAPE='FILLED';
   direction='IN';
   linethickness = 6;
   widthunit ="pixel";
   linecolor = "red"; 
   x1=97; x2=97; 
   y1=62; y2=78; output;
   linecolor = "lightgreen"; 
   y1=98; y2=82; output;
run;
 
data anno;
   length function $20;
   set anno1 anno2;
run;
 
%do k = 1 %to %sysfunc(countw(&Al,|));
%do i = 1 %to %sysfunc(countw(&Bl,|));
%do j = 1 %to %sysfunc(countw(&Cl,|));
data ingraph;
       set gdata; 
       if A="%qscan(%superq(Al),&k,|)" and B=%qscan(%superq(Bl),&i,|) and  C=%qscan(%superq(Cl),&j,|);
run;
...
...
proc sgplot data=ingraph dattrmap=attribap sganno=anno noautolegend;
   by visit;
   vbar Position / group=xxx attrid=ID1 response=yyy barwidth=0.3;
   refline 0 / axis=y lineattrs=(pattern=shortdash);
   xaxis label="ID" VALUESROTATE=VERTICAL fitpolicy=rotate;
   yaxis label="Change for &B" offsetmax=0.025 offsetmin=.025 values=(&miny. to &maxy. by &inc.);
   legenditem type=markerline name='item1' / lineattrs=(pattern=Solid color=CX0085B2)                 markerattrs=(symbol=squarefilled color=CX0085B2); 
   legenditem type=markerline name='item2' / lineattrs=(pattern=Solid color=CX808080) markerattrs=(symbol=squarefilled color=CX808080);
   keylegend 'item1' 'item2' / noborder;
run;

...

3 REPLIES 3
ballardw
Super User

Without actual data, or a much clearer description of how all your different graphs will vary, it is not going to be possible to provide code.

 

If this were my project I think I would investigate adding data to the plot data set(s) to create VECTOR plots for the arrows. Since this would move the arrows into the graph area you would need to set xaxis options to include your current range of values plus a bit to set the xorigin for the vectors. Your yorigin would be a small offset positive and negative from 0 and set the x, y coordinates for the pair for each plot to be in the range. Whether one vector with a Group option would work better than two vector plots hard to tell.

A TEXT plot code provide the text to go with the vectors

Ksharp
Super User
1) You could use the following option of PROC SGPLOT to make uniform scale of Y axis for different page.
UNIFORM=GROUP | SCALE | ALL | XSCALE | YSCALE | XSCALEGROUP | YSCALEGROUP
specifies how to control axis scaling and legends when you use a BY statement.
2)You could also specify BASELINE=0 option of VBAR to force it be zero ,then you don't need to consider of shift/offset.

3) Alternative way is to make a macro, specify a macro parameter to represent this baseline value ,and a visit for a macro ,ne need BY statement.
DanH_sas
SAS Super FREQ

The key for doing what you requested is to use different drawing spaces. You should set the drawing space for the Y coordinate you want to zero to be Y1SPACE="DATAVALUE" and Y1=0. That way, the arrows will follow the zero tick on the Y-axis regardless of where it is drawn. The other coordinates can be drawn in other drawing spaces. For your use case, I would tend to set X1SPACE and X2SPACE to be WALLPERCENT, and set X1 and X1 to be values greater than 100. That way, the arrows are drawn outside of the wall at a consistent distance from the wall, regardless of graph size.

 

Hope this helps!

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

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

View all other training opportunities.

Discussion stats
  • 3 replies
  • 756 views
  • 2 likes
  • 4 in conversation