BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
grsanford
Fluorite | Level 6

Hello, 

 

I am working with SGPanel to produce graphics of soil health metrics associated with different agricultural management. I've been using box plots but would love to work with density plots as a colleageu of mine has done using R (see attached figure). Is it possible to add shading and mean reference lines with sgplanel? I am comfortable with using annotation data sets to add labels but figure there must be a straightforward way to shade and add reflines for the means... Any help would be much appreciated! Thank you. 

 

proc sgpanel data=SI_ESM_2022;
panelby systrt / novarname rows=3 columns=1 noheader;
density pox_mg_cm2 / group=systrt type=kernel;
keylegend / noborder position=bottom title="Cropping System";
format SItrt SItrt.;
format systrt systrt.;
run;

 

dist panel.png

1 ACCEPTED SOLUTION

Accepted Solutions
yabwon
Onyx | Level 15

How about combining both box-plot and the distribution (kernel) plot with help of BasePlus package and %RainCloudPlot() macro?

 

Fore example:

 

yabwon_1-1684502047462.png

 

 

The basePlus package is available here: https://github.com/SASPAC/baseplus

 

The documentation for the macro is here.

 

All the best

Bart

 

P.S. How to get BasePlus?

To work with SAS Packages like BasePlus or others you will need SAS Packages Framework.

 

Lets assume your SAS session has access to the internet (if not look below).

1) Create a directory where you want to store SPF and packages, for example let it be: "/home/myuserid/SASpackages" under Linux or "C:\Users\myuserid\SASpackages" under Windows.

2) Run the following code only one time to get the SPF:

filename packages "/home/myuserid/SASpackages"; /* setup directory for packages */
filename SPFinit url "https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas";
%include SPFinit; /* enable the framework */

%installPackage(SPFinit) /* install SPF */
%installPackage(BasePlus) /* install BasePlus */

(installation of other packages goes the same way - by installPackage macro).

3) From now on, in this and any new SAS session, to enable SPF and BasePlus just run:

filename packages "/home/myuserid/SASpackages"; /* setup directory for packages */
%include packages(SPFinit.sas); /* enable the framework */

%loadPackage(BasePlus)    /* load the package content into the SAS session */

4) Enjoy 

 

P.S.2

No access to the internet on your machine? No problem! Instead step number 2 go here and manually download SPFinit.sas file. Then go to here and download baseplus.zip file. Store them in the directory from step 1 and proceed to step 3.

 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



View solution in original post

22 REPLIES 22
ballardw
Super User

What are your rules for "shading"? The levels of the GROUP= variable are used to control appearance of such things. So your graph by default should show different colors. You can override the colors of your current plot with either a STYLEATTRS statement affecting the options used, or a DATTRMAP data set.

 

Those are not REFLINES, as Sgpanel and Sgplot consider them. SAS Reflines extend from boundary to boundary.

I think you need a step to 1) get the horzontal mean for each group of values given the density, 2) determine the y value associated then add that information to your data for a HIGHLOW plot (if you have different y bases for each plot as the example shows)

I may be that exporting the data that graph creates

Likely need some data to get anything resembling working code though.

 

Here is an example using a data set that you should have to do a simple density graph, get the coordinates of the curves and find the mean x for each:

ods output sgpanel=paneldata;
proc sgpanel data=sashelp.heart noautolegend;
  title "Cholesterol Distribution in Heart Study";
  panelby sex;
  density cholesterol /type=kernel;
run;


Proc summary data=paneldata nway;
   class sex;
   var KERNEL_Cholesterol___X;
   weight  KERNEL_Cholesterol___Y;
   output out=panelmeans mean=xmean;
run;

Probably have to interpolate between a couple points in the Paneldata set to get the associated Y variable. Note that the names in the paneldata data set are built from the options (type) and variables you supply as density and group variables.

grsanford
Fluorite | Level 6

Thank you ballardw I'd appreciate any additional help you might be willing to offer. I've attached the code I started with and a subset of the data that relates to the code. Please let me know if this is sufficient to work with. Thank you!

ballardw
Super User

Many users here don't want to download Excel files because of virus potential, others have such things blocked by security software. Also if you give us Excel we have to create a SAS data set and due to the non-existent constraints on Excel data cells the result we end up with may not have variables of the same type (numeric or character) and even values.

 

Instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show how to turn an existing SAS data set into data step code that can be pasted into a forum code box using the </> icon or attached as text to show exactly what you have and that we can test code against.

grsanford
Fluorite | Level 6

ballardw, here a the .txt version of the data. Will this work? If not I've also pasted the data below. Thank you.  

 

SItrt systrt phtrt pox_mg_cm2
4 2 2 12.88696113
1 2 2 11.94738293
3 2 2 11.63248155
5 2 2 12.17536777
0 2 2 11.76687135
2 2 2 11.85246942
2 3 3 13.68218879
1 3 3 13.16944579
4 3 3 12.86394351
5 3 3 14.79899238
0 3 3 12.47548201
3 3 3 12.79245959
4 3 2 14.64057942
1 3 2 14.41537916
0 3 2 14.48867916
5 3 2 16.01924437
2 3 2 15.73376559
3 3 2 13.94946124
0 3 1 13.99047601
1 3 1 12.27262767
2 3 1 13.46137891
3 3 1 14.3106362
5 3 1 15.72065398
4 3 1 14.29409688
5 2 1 13.61729923
3 2 1 13.16995377
2 2 1 12.47854709
0 2 1 12.35009414
1 2 1 11.88548512
4 2 1 12.58802618
3 1 1 13.27844604
0 1 1 12.1562645
4 1 1 11.7116175
1 1 1 12.33319876
5 1 1 12.60406808
2 1 1 13.43035937
2 3 2 14.43188334
5 3 2 14.61942166
1 3 2 13.01032142
3 3 2 14.17217537
4 3 2 13.6444612
0 3 2 14.01900035
3 2 2 12.86193064
0 2 2 14.26545578
1 2 2 13.26167787
4 2 2 12.99590279
2 2 2 13.50167571
5 2 2 14.00317787
4 1 1 13.81625328
2 1 1 11.56360043
1 1 1 12.43069582
3 1 1 13.35723233
0 1 1 11.94852263
5 1 1 11.66410866
4 3 1 14.41264875
3 3 1 12.99407907
5 3 1 14.41562749
0 3 1 15.38040471
2 3 1 15.1052037
1 3 1 15.28369608
3 2 1 15.20596638
2 2 1 15.22494164
5 2 1 13.46228793
1 2 1 13.78815025
0 2 1 12.52566363
4 2 1 13.75046544
1 3 3 11.857395
3 3 3 13.66492998
0 3 3 12.77760399
2 3 3 14.1794187
4 3 3 14.13259043
5 3 3 13.61236715
0 2 2 14.29350549
2 2 2 11.45586665
1 2 2 11.76403139
4 2 2 13.97497816
5 2 2 13.22868457
3 2 2 14.41861076
4 3 2 14.44806295
1 3 2 13.99093983
5 3 2 11.99566619
0 3 2 13.82929793
2 3 2 13.58568729
3 3 2 11.2628244
3 3 3 14.85429739
2 3 3 15.73293878
5 3 3 12.47826303
0 3 3 16.04129749
4 3 3 14.67840285
1 3 3 13.31204488
4 2 1 14.33736015
1 2 1 15.06686638
2 2 1 12.58073226
0 2 1 11.40057684
5 2 1 14.67076777
3 2 1 12.68404915
5 3 1 14.50961412
3 3 1 13.67793578
2 3 1 14.12370018
1 3 1 12.87724315
4 3 1 15.01424042
0 3 1 15.40967415
5 1 1 14.48826615
3 1 1 15.41547834
1 1 1 12.4603278
0 1 1 14.26025864
4 1 1 14.50813508
2 1 1 12.54865376

Ksharp
Super User

How about this one ?

 

 

proc import datafile='C:\temp\a\SIsoils-2023-05-18ex.xlsx' DBMS=XLSX OUT=SIsoils REPLACE; *import SIsoils data;
run;

proc format;
value SItrt
0 = 'Control'
1 = 'Add Cover'
2 = 'Reduce Tillage'
3 = 'Add Manure'
4 = 'Combine - Grain'
5 = 'Combine - Silage'
;
value systrt 
1 = 'Maize'
2 = 'M-S'
3 = 'M-S-W(org)'
;
value phtrt 
1 = 'Maize'
2 = 'Soybeans'
3 = 'Small Grains'
;
run;


proc sort data=SIsoils out=have;
by systrt;
run;
proc summary data=have;
by systrt;
var pox_mg_cm2;
output out=mean(drop=_type_ _freq_) mean=mean;
run;


ods select none;
ods output sgpanel=sgpanel;
proc sgpanel data=have;
panelby systrt / novarname rows=3 columns=1 noheader;
density pox_mg_cm2 / group=systrt transparency=0 type=kernel;
keylegend / noborder position=bottom title="Cropping System";
format SItrt SItrt.;
format systrt systrt.;
run;
ods select all;


data sgpanel2;
merge sgpanel mean;
by systrt;
output;
call missing(of _all_);
run;


ods graphics/noborder;
proc sgpanel data=sgpanel2;
panelby KERNEL_POX_MG_CM2_GROUP_SYST__GP/layout=rowlattice novarname noheader;
series x=KERNEL_POX_MG_CM2_GROUP_SYST___X y=KERNEL_POX_MG_CM2_GROUP_SYST___Y
/group=KERNEL_POX_MG_CM2_GROUP_SYST__GP lineattrs=(thickness=2);
refline mean/axis=x lineattrs=(thickness=2 color=red);
keylegend / noborder position=bottom title="Cropping System";

band x=KERNEL_POX_MG_CM2_GROUP_SYST___X lower=0 upper=KERNEL_POX_MG_CM2_GROUP_SYST___Y
/group=KERNEL_POX_MG_CM2_GROUP_SYST__GP transparency=0.8; 
run;

Ksharp_0-1684499448104.png

 

grsanford
Fluorite | Level 6

Ksharp, thank you very much. I was able to get this to work and really appreciate the help!

yabwon
Onyx | Level 15

How about combining both box-plot and the distribution (kernel) plot with help of BasePlus package and %RainCloudPlot() macro?

 

Fore example:

 

yabwon_1-1684502047462.png

 

 

The basePlus package is available here: https://github.com/SASPAC/baseplus

 

The documentation for the macro is here.

 

All the best

Bart

 

P.S. How to get BasePlus?

To work with SAS Packages like BasePlus or others you will need SAS Packages Framework.

 

Lets assume your SAS session has access to the internet (if not look below).

1) Create a directory where you want to store SPF and packages, for example let it be: "/home/myuserid/SASpackages" under Linux or "C:\Users\myuserid\SASpackages" under Windows.

2) Run the following code only one time to get the SPF:

filename packages "/home/myuserid/SASpackages"; /* setup directory for packages */
filename SPFinit url "https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas";
%include SPFinit; /* enable the framework */

%installPackage(SPFinit) /* install SPF */
%installPackage(BasePlus) /* install BasePlus */

(installation of other packages goes the same way - by installPackage macro).

3) From now on, in this and any new SAS session, to enable SPF and BasePlus just run:

filename packages "/home/myuserid/SASpackages"; /* setup directory for packages */
%include packages(SPFinit.sas); /* enable the framework */

%loadPackage(BasePlus)    /* load the package content into the SAS session */

4) Enjoy 

 

P.S.2

No access to the internet on your machine? No problem! Instead step number 2 go here and manually download SPFinit.sas file. Then go to here and download baseplus.zip file. Store them in the directory from step 1 and proceed to step 3.

 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



grsanford
Fluorite | Level 6

yabwon, YES!!! This is Brilliant!!! I've never worked with the SAS packages framework. I have SAS Enterprise guide the my University so this should work? I will let you know how far I get. Thank you!

grsanford
Fluorite | Level 6

yabwon, I am making progress (thank you very much) but have a few questions. I have never worked with macro's before (shocking, I know). Is there a way to use my format dataset and annotation datsets with the figure produced? For example I'd like to label the group variable in orders that might not always be alphanumeric (hence format dataset), and I'd like to include statistical model output on the figure (test of fixed effects etc.), hence the annotate dataset. I'd appreciate your thoughts on this. Thank you!

rain cloud plot - sanford.png

yabwon
Onyx | Level 15

@grsanford 

If you have format for a given variable you can use "formated=1" which will use format for display. Run this and compare results:

proc format;
value system
1="Windows"
2="MacOS"
3="Linux"
;
run;

data test;
  do system= 1 to 3;
    do i= 1 to 30;
      x = rannor(123)+system;
      output;
    end;
  end;
  format system system.;
run;

%RainCloudPlot(test, system, x)

%RainCloudPlot(test, system, x, formated=1)

If it is about adding annotations it won't be so easy "out of the box". At the moment when I was designing and implementing that macro I was not thinking about using annotation dataset. If you describe what would you like to get I could try to modify the macro for that purpose. But it wont be instant, and will take me some time.

 

If you would like to examine the code of the macro you could use the %previewPackge() macro. Basically:

%previewPackage(BasePlus,RainCloudPlot)

will print out into the log all the code of the %rainCloudPlot(), so you could copy it and play.

 

Bart

 

 

 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



yabwon
Onyx | Level 15

Ok, I did some reading. if you basically have a dataset with annotations and want just to do something like:

proc sgplot data=myData sganno=myAnnotations;
 /* some plot here */
run;

it shouldn't be a problem to add such feature and it shouldn't be very time consuming.

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



yabwon
Onyx | Level 15

I modified the %RainCloudPlot() macro so you can add annotations to the plot, try with this example:


  data annotation; 
    function="text";
    label="This graph is full(*ESC*){sup '2'} of annotations!";
    drawspace="graphpercent";
    rotate=30;
    anchor="center";
    textsize=32;
    x1=50;
    y1=50;
    textcolor="red"; 
    justify="center";
    textweight="bold";
    width=100;
    widthunit="percent";
  run; 

  proc format;
    value system
    1="Windows"
    2="MacOS"
    3="Linux"
    ;
  run;

  data test;
    do system = 1 to 3;
      do i = 1 to 30;
        x = rannor(123)/system;
        output;
      end;
    end;
    format system system.;
  run;


  %RainCloudPlot(test, system, x
  , formated=1
  , sganno=annotation
  , sgPlotOptions=noborder
  , WidthPX=2000
  , HeightPX=420
  )

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



grsanford
Fluorite | Level 6

Bart, Thank you so very much for all of this help. I did get format to work! I did not get the annotation to work. When I run your example code my log shows. 

 

grsanford_0-1684868278245.png

Do I need to reinstall the macro? Currenly my code opens with. 

 

filename packages 'C:/SAS_PACKAGES'; /* setup directory for packages */
%include packages(SPFinit.sas); /* enable the framework */

%loadPackage(BasePlus) /* load the package content into the SAS session */

 

While I am asking question I wonder if you could also explain how I would change the default colors. I did try something like:

 

colorlist=(CX0072B2 CXF0E442 CXCC79A7)

 

but failed... 

yabwon
Onyx | Level 15

Hi,

 

Yes, you have to install new version of the package (and framework too {it was updated too])

Open new session and run:

filename packages 'C:/SAS_PACKAGES';
%include packages(SPFinit.sas);
%installPackage(SPFinit BasePlus)

Close the session, start new and run your "usual" code:

filename packages 'C:/SAS_PACKAGES'; /* setup directory for packages */
%include packages(SPFinit.sas); /* enable the framework */
%loadPackage(BasePlus) /* load the package content into the SAS session */

BTW if you run:

%helpPackage(BasePlus, RainCloudPlot)

you will get help on RainCloudPlot macro printed in the log.

 

Bart

 

 

 

 

 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 22 replies
  • 3308 views
  • 3 likes
  • 4 in conversation