Hi,
I am trying to create a patient journey graph using SGPlot, In scatter plot I am not able to put datalabels values into some symbol like square or triangle. As I have multiple measurement marks of a patient. I need to differentiate them visually.
Please help me in this. Sharing a dummy data and code that I have used to generate SGPlot.
Data
data sample_data; input PATID$ improvement_test_age TRT1_Age TRT2_Age improvement_marks first_visit_age last_visit_age group$; datalines; 1 40 40 0 0 32 136 Group-1 1 136 40 0 10 32 136 Group-1 2 144 160 96 2 48 288 Group-3 2 168 160 96 2 48 288 Group-3 2 224 160 96 3 48 288 Group-3 2 280 160 96 4 48 288 Group-3 3 8 88 0 1 32 176 Group-1 3 56 88 0 2 32 176 Group-1 3 88 88 0 4 32 176 Group-1 3 120 88 0 10 32 176 Group-1 3 168 88 0 10 32 176 Group-1 4 136 128 0 3 48 304 Group-1 4 208 128 0 4 48 304 Group-1 4 248 128 0 7 48 304 Group-1 4 296 128 0 4 48 304 Group-1 5 104 80 0 4 24 136 Group-1 5 136 80 0 4 24 136 Group-1 6 160 168 0 7 96 320 Group-1 6 320 168 0 7 96 320 Group-1 7 128 136 0 1 136 176 Group-1 7 168 136 0 6 136 176 Group-1 8 304 0 136 3 24 424 Group-3 8 400 0 136 4 24 424 Group-3 9 248 0 152 3 96 312 Group-3 9 312 0 152 2 96 312 Group-3 10 32 56 24 1 0 200 Group-3 10 152 56 24 3 0 200 Group-3 11 64 48 24 0 8 168 Group-3 11 120 48 24 4 8 168 Group-3 11 168 48 24 5 8 168 Group-3 12 192 136 0 2 48 192 Group-1 12 192 136 0 4 48 192 Group-1 13 144 136 72 4 48 296 Group-3 13 192 136 72 4 48 296 Group-3 13 240 136 72 4 48 296 Group-3 14 48 16 0 0 16 192 Group-1 14 112 16 0 0 16 192 Group-1 14 144 16 0 4 16 192 Group-1 14 192 16 0 4 16 192 Group-1 15 80 80 0 9 48 200 Group-1 15 96 80 0 9 48 200 Group-1 15 152 80 0 9 48 200 Group-1 15 200 80 0 4 48 200 Group-1 16 192 160 0 8 88 336 Group-1 16 232 160 0 9 88 336 Group-1 16 264 160 0 9 88 336 Group-1 16 304 160 0 6 88 336 Group-1 17 168 120 0 9 40 248 Group-1 17 248 120 0 9 40 248 Group-1 18 104 104 0 5 48 208 Group-1 18 128 104 0 6 48 208 Group-1 18 200 104 0 4 48 208 Group-1 19 208 136 128 2 72 256 Group-3 19 256 136 128 4 72 256 Group-3 20 504 0 296 9 192 600 Group-3 20 520 0 296 9 192 600 Group-3 21 152 152 0 4 112 248 Group-1 21 232 152 0 7 112 248 Group-1 22 200 112 0 8 80 328 Group-1 22 232 112 0 8 80 328 Group-1 22 272 112 0 9 80 328 Group-1 22 304 112 0 8 80 328 Group-1 23 184 184 0 9 24 232 Group-2 23 232 184 0 9 24 232 Group-2 24 200 168 112 4 48 256 Group-3 24 248 168 112 4 48 256 Group-3 25 192 192 0 4 144 296 Group-1 25 264 192 0 9 144 296 Group-1 26 80 88 0 0 56 168 Group-1 26 136 88 0 4 56 168 Group-1 27 136 144 0 2 32 360 Group-1 27 208 144 0 0 32 360 Group-1 27 360 144 0 4 32 360 Group-1 ; Run;
Code
ods graphics on / height=15in; TITLE "Patient Journey"; proc sgplot data= sample_data NOAUTOLEGEND; SYMBOLCHAR name=markern char='FF2F'x; SYMBOLCHAR name=markerA char='0042'x; HIGHLOW Y = PATID LOW=first_visit_age HIGH=last_visit_age/ group = group Name= "Group" Type = bar NOMISSINGGROUP NOOUTLINE barwidth= 0.2 FILLATTRS=(TRANSPARENCY=.50); SCATTER Y=PATID X=TRT1_Age/ markerattrs=(symbol=markerA size=14) name="T1" legendlabel="Treatment 1"; SCATTER Y=PATID X=TRT2_Age/ markerattrs=( symbol=markern size=13) name="T2" legendlabel="Treatment 2" ; SCATTER Y=PATID X=improvement_test_age/ datalabel=improvement_marks datalabelattrs=( color=black size=5) markerattrs=( size=3) Name = "Improvement Marks"; XAXIS LABEL="Age (months)" VALUES=(0 TO 600 BY 25 ) valueshint ; YAXIS LABEL="Patient ID" type=discrete fitpolicy=none; keylegend "T1" "T2" "Group" "Improvement Marks"; RUN;
I wasn't sure which variable you wanted to used for your borders, but the code below should give you the idea on how to get the borders. I created an attributes map for the values in your "group" column. Then, I associated the map to a SCATTER statement right before the TEXT statement used to render your improvement marks. Let me know if you have any questions about the code.
Thanks!
Dan
data borders;
retain ID "borders";
length markersymbol $ 8;
input value $ markersymbol $;
cards;
Group-1 circle
Group-2 square
Group-3 triangle
;
run;
ods graphics on / height=15in;
TITLE "Patient Journey";
proc sgplot data= sample_data NOAUTOLEGEND dattrmap=borders;
SYMBOLCHAR name=markern char='FF2F'x;
SYMBOLCHAR name=markerA char='0042'x;
HIGHLOW Y = PATID LOW=first_visit_age HIGH=last_visit_age/
group = group Name= "Group" Type = bar NOMISSINGGROUP NOOUTLINE barwidth= 0.2 FILLATTRS=(TRANSPARENCY=.50);
SCATTER Y=PATID X=TRT1_Age/
markerattrs=(symbol=markerA size=14) name="T1" legendlabel="Treatment 1";
SCATTER Y=PATID X=TRT2_Age/
markerattrs=( symbol=markern size=13) name="T2" legendlabel="Treatment 2" ;
SCATTER Y=PATID X=improvement_test_age/ markerattrs=( size=3) Name = "Improvement Marks";
SCATTER Y=PATID X=improvement_test_age/ markerattrs=(size=11 color=black) attrid=borders group=group;
TEXT Y=PATID X=improvement_test_age text=improvement_marks / textattrs=(color=black size=5) strip;
XAXIS LABEL="Age (months)" VALUES=(0 TO 600 BY 25 ) valueshint ;
YAXIS LABEL="Patient ID" type=discrete fitpolicy=none;
keylegend "T1" "T2" "Group" "Improvement Marks";
RUN;
Instead of using DATALABEL on the SCATTER plot, trying using a TEXT plot overlaid on the SCATTER plot:
SCATTER Y=PATID X=improvement_test_age/ markerattrs=( size=3) Name = "Improvement Marks";
TEXT Y=PATID X=improvement_test_age text=improvement_marks / textattrs=(color=black size=5) strip;
Hope this helps!
Dan
Thanks @DanH_sas. I need some border(Square/Triangle/Circle) around the text.
What variable controls the shape of the border?
@SouravK , do you still have a question about creating the different-shaped borders?
I wasn't sure which variable you wanted to used for your borders, but the code below should give you the idea on how to get the borders. I created an attributes map for the values in your "group" column. Then, I associated the map to a SCATTER statement right before the TEXT statement used to render your improvement marks. Let me know if you have any questions about the code.
Thanks!
Dan
data borders;
retain ID "borders";
length markersymbol $ 8;
input value $ markersymbol $;
cards;
Group-1 circle
Group-2 square
Group-3 triangle
;
run;
ods graphics on / height=15in;
TITLE "Patient Journey";
proc sgplot data= sample_data NOAUTOLEGEND dattrmap=borders;
SYMBOLCHAR name=markern char='FF2F'x;
SYMBOLCHAR name=markerA char='0042'x;
HIGHLOW Y = PATID LOW=first_visit_age HIGH=last_visit_age/
group = group Name= "Group" Type = bar NOMISSINGGROUP NOOUTLINE barwidth= 0.2 FILLATTRS=(TRANSPARENCY=.50);
SCATTER Y=PATID X=TRT1_Age/
markerattrs=(symbol=markerA size=14) name="T1" legendlabel="Treatment 1";
SCATTER Y=PATID X=TRT2_Age/
markerattrs=( symbol=markern size=13) name="T2" legendlabel="Treatment 2" ;
SCATTER Y=PATID X=improvement_test_age/ markerattrs=( size=3) Name = "Improvement Marks";
SCATTER Y=PATID X=improvement_test_age/ markerattrs=(size=11 color=black) attrid=borders group=group;
TEXT Y=PATID X=improvement_test_age text=improvement_marks / textattrs=(color=black size=5) strip;
XAXIS LABEL="Age (months)" VALUES=(0 TO 600 BY 25 ) valueshint ;
YAXIS LABEL="Patient ID" type=discrete fitpolicy=none;
keylegend "T1" "T2" "Group" "Improvement Marks";
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!
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.
Ready to level-up your skills? Choose your own adventure.