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

I have this pretty KM/results plot using 9.3 proc template

SGRender3.png

What I would like is the numbers at the bottom of the plot to be the same colour as the KM bit. ie the numbers for drug to be blue and the comp to be red.

I assumed using class="signvar" in the blockplot statement it would do this but, as you can see all Im getting is black.

code is:

proc template;
  define statgraph SurvivalPlotAtRisk_Outside_Scatter;
   dynamic _x _cens _surv _trt _Xlabel _ylabel _min _max _by _num;
   begingraph;
     discreteattrmap name="colorbysign" / ignorecase=true;
value "Comp" /
    fillattrs=GraphData1(color=red )
       markerattrs=GraphData1(color=red )
       lineattrs=GraphData1(color=red );
    value "DRUG" /
    fillattrs=GraphData1(color=blue )
       markerattrs=GraphData1(color=blue )
       lineattrs=GraphData1(color=blue );   
  enddiscreteattrmap;

       legenditem type=line name="DRUG" / LABEL="DRUG (N=&NT1, [Events=&nevent1])" lineattrs=GraphData1(color=blue THICKNESS=1)
                   labelattrs=(size=9 family="Arial") ;
    legenditem type=marker name="DRUG2" / LABEL="Median Survival: &Med_DRUG " lineattrs=GraphData1(color=blue THICKNESS=10)
          labelattrs=(size=9 family="Arial") markerattrs=(size=0);;
    legenditem type=line name="Comp" / LABEL="Comparator (N=&NT2, [Events=&nevent2])" lineattrs=GraphData1(color=red THICKNESS=1)
          labelattrs=(size=9 family="Arial");;
    legenditem type=marker name="Comp2" / LABEL="Median Survival: &med_comp" lineattrs=GraphData1(color=red THICKNESS=10)
          labelattrs=(size=9 family="Arial") markerattrs=(size=0);;
    legenditem type=marker name="BLANK" / LABEL="" lineattrs=GraphData1
          labelattrs=(size=9 family="Arial") markerattrs=(size=0);;
    legenditem type=marker name="HR" / LABEL="Hazard Ratio (95%CI): &HR" lineattrs=GraphData1(color=black THICKNESS=10)
          labelattrs=(size=9 family="Arial") markerattrs=(size=0);;
    legenditem type=marker name="PValue" / LABEL="Log rank test: p=&PValue" lineattrs=GraphData1(color=black THICKNESS=10)
          labelattrs=(size=8 family="Arial") markerattrs=(size=0);;
    legenditem type=marker name="risk" / LABEL="No. of subjects at risk:" lineattrs=GraphData1(color=black THICKNESS=10)
          labelattrs=(size=8 family="Arial") markerattrs=(size=0);;

      discreteattrvar attrvar=signvar var=_trt attrmap="colorbysign"; 
        layout overlay / yaxisopts=(linearopts=(viewmin=0))
               xaxisopts=( linearopts=
                      ( tickvaluesequence=(start=_min end=_max increment=_by) )
                       label=_xlabel )
          yaxisopts=(label=_ylabel );
        stepplot x=_x y=_surv / group=signvar lineattrs=(pattern=solid) name='s';
           scatterplot x=_x y=_cens / markerattrs=(symbol=plus) GROUP=signvar  ;
        innermargin;
         blockplot x=_x block=_num / class="signvar"
                            display=(values label) valuehalign=start
                            valueattrs=(size=8 ) labelattrs=(size=8);
        endinnermargin;
      discretelegend "PValue" "risk"/ /*title=_label*/ titleattrs=(size=9 family="Arial")
                                BORDER=false across=1
           location=inside
                                halign=left valign=bottom ;
      discretelegend "DRUG" "DRUG2" "Comp" "Comp2" "BLANK" "HR"/ /*title=_label*/ titleattrs=(size=9 family="Arial")
                                BORDER=false across=1
           location=inside
                                halign=right valign=top ;

  endlayout;
  endgraph;
  end;
run;


proc sgrender data=fig_surv2 template=SurvivalPlotAtRisk_Outside_Scatter;
dynamic _x    = 'surover'
         _cens = 'censval'
   _surv = 'survival'
   _trt  = 'trtpn'
   _Ylabel = 'Survival Distribution Function'
   _xlabel = 'Time (Days)'
   _min='0'
   _max='1700'
   _by='100'
   _num='left'
;
run;

1 ACCEPTED SOLUTION

Accepted Solutions
DanH_sas
SAS Super FREQ

In SAS 9.4, this would be trivial. You would use an AXISTABLE instead of a BLOCKPLOT, and you would have the control you need to color the text by class (along with a lot of other features). However, to do this in SAS 9.3, you will need to use a little scatterplot trickery. In the example below, I create a discrete scatterplot on the Y2 axis and adjust the axis offsets so that the two plots do not collide. Then, I just use the MARKERCHARACTER options to plot the text and GROUP role to color it.

Hope this helps!

Dan

proc means data=sashelp.class nway;

class age sex;

var height;

output out=tempdata mean=;

run;

proc template;

define statgraph plot;

begingraph;

layout overlay / yaxisopts=(offsetmin=0.1) y2axisopts=(offsetmax=0.95);

  seriesplot x=age y=height / group=sex;

  scatterplot x=age y=sex / group=sex yaxis=y2 markercharacter=height;

endlayout;

endgraph;

end;

run;

proc sgrender data=tempdata template=plot;

format height F5.2;

run;

View solution in original post

7 REPLIES 7
DanH_sas
SAS Super FREQ

In SAS 9.4, this would be trivial. You would use an AXISTABLE instead of a BLOCKPLOT, and you would have the control you need to color the text by class (along with a lot of other features). However, to do this in SAS 9.3, you will need to use a little scatterplot trickery. In the example below, I create a discrete scatterplot on the Y2 axis and adjust the axis offsets so that the two plots do not collide. Then, I just use the MARKERCHARACTER options to plot the text and GROUP role to color it.

Hope this helps!

Dan

proc means data=sashelp.class nway;

class age sex;

var height;

output out=tempdata mean=;

run;

proc template;

define statgraph plot;

begingraph;

layout overlay / yaxisopts=(offsetmin=0.1) y2axisopts=(offsetmax=0.95);

  seriesplot x=age y=height / group=sex;

  scatterplot x=age y=sex / group=sex yaxis=y2 markercharacter=height;

endlayout;

endgraph;

end;

run;

proc sgrender data=tempdata template=plot;

format height F5.2;

run;

Adie_efc
Calcite | Level 5

oh..I missed the response for this. I'll give it a go...thanks.

Adie_efc
Calcite | Level 5

Thanks it worked fine. The only thing I had to change was to add a pad to my legend (text) items at the bottom and to create a new re-ordered treatment variable.

have attached an image of the plot Ive created.

SGRender40.png

Jay54
Meteorite | Level 14

Since you are using GTL, you can put the at risk table in a separate cell below the survival curves and get the treatment labels to the left.

Adie_efc
Calcite | Level 5

Sanjay,

I can only do that in 9.4 though? Im using sas 9.3.

Adie.

Jay54
Meteorite | Level 14

You can do that with SAS 9.3.  The AXISTABLE statement Dan mentioned is new in SAS 9.4.  You are not using axistable but scatterplot with markercharacter.  This is available since SAS 9.2.

Adie_efc
Calcite | Level 5

Thanks. Im guessing this would use a multi layout plot rather than the one I have as the moment.

Im going to leave it as is as my code is way too complex and sods law would say it would take me longer to recode, what seems to be simple changes has knock onto to other bits (ie the simple change to scatter plot messed up my legend).

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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.

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
  • 7 replies
  • 2539 views
  • 0 likes
  • 3 in conversation