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

Note the x-axis is month and day (no year) while the y-axis is year.  The graph would be simple to replicate using Proc Sgscatter, but how do I get month and day without the year?  I could extract the month and day from each date, then construct a "dummy date" where they retain the original month and day but all with the same year and only display the month and day.  Is there a better way?

menhaden landings.PNG

1 ACCEPTED SOLUTION

Accepted Solutions
GraphGuy
Meteorite | Level 14

Here's an alternate way, if you want to get the *exact* same plot.  I use a custom Gplot, with a bit of date manipulation and a bit of annotate.  Below is the SAS/Graph output, and the code I used:

roe_menhaden_plot.png

%let name=roe_menhaden_plot;

filename odsout '.';

/*

A scatter plot of dates when roe menhaden were landed at

Beaufort, North Carolina, 1988-1999.  Using estimated data

from Figure 2 in the following paper:

http://spo.nwr.noaa.gov/mfr621/mfr6211.pdf

You can't really get this graph by default, and you have to

use a few little "tricks" ... look for 'Trick' in the comments...

*/

data fish_data;

informat catch_date date9.;

format catch_date date9.;

input catch_date;

datalines;

25oct1988

04nov1988

09nov1988

12nov1988

15nov1988

22nov1988

25nov1988

27nov1988

03dec1988

08dec1988

10dec1988

14dec1988

27dec1988

30dec1988

03jan1989

09jan1989

11jan1989

12oct1989

14oct1989

17oct1989

09nov1989

13nov1989

14nov1989

22nov1989

30nov1989

03jan1990

03nov1990

07nov1990

14nov1990

21nov1990

23nov1990

26nov1990

27nov1990

28nov1990

03dec1990

07dec1990

10dec1990

14dec1990

20dec1990

27dec1990

03jan1991

04jan1991

08jan1991

11jan1991

19jan1991

05nov1991

06nov1991

07nov1991

08nov1991

18nov1991

19nov1991

31dec1991

22jan1992

30oct1992

08nov1992

10nov1992

13nov1992

17nov1992

19nov1992

24nov1992

28nov1992

03dec1992

04dec1992

08dec1992

09dec1992

03nov1993

12nov1993

15nov1993

16nov1993

17nov1993

22nov1993

29nov1993

30nov1993

01dec1993

02dec1993

03dec1993

04dec1993

06dec1993

08dec1993

14dec1993

08nov1994

14nov1994

15nov1994

24nov1994

25nov1994

26nov1994

27nov1994

06dec1994

16nov1995

17nov1995

18nov1995

20nov1995

22nov1995

24nov1995

27nov1995

04dec1995

06dec1995

13dec1995

16dec1995

10nov1996

11nov1996

12nov1996

18nov1996

21nov1996

25nov1996

29nov1996

30nov1996

13dec1996

16dec1996

17dec1996

20jan1997

16nov1997

17nov1997

20nov1997

26nov1997

27nov1997

28nov1997

29nov1997

07dec1997

10dec1997

11dec1997

18dec1997

19dec1997

02nov1998

09nov1998

13nov1998

15nov1998

16nov1998

22nov1998

27nov1998

28nov1998

30nov1998

01dec1998

02dec1998

06dec1998

30nov1999

05dec1999

06dec1999

07dec1999

19dec1999

28dec1999

29dec1999

30dec1999

31dec1999

;

run;

data fish_data; set fish_data;

day=.; day=trim(left(put(catch_date,day.)));

month_name=trim(left(put(catch_date,monname20.)));

year=.; year=trim(left(put(catch_date,year4.)));

if month_name='January' then fishing_year=year-1;

else fishing_year=year;

/*

Trick #1 ... I'm converting the catch_date to a 1988 date,

so they can all be plotted along the same x-axis.

*/

plot_date=catch_date-((fishing_year-1988)*365.25);

run;

/*

Trick #2 - I annotate the tickmarks, and dates & months,

along the x-axis, so I can get them exactly the way I want.

*/

data anno_days;

informat catch_date date9.;

format catch_date date9.;

input catch_date;

datalines;

05oct1988

10oct1988

15oct1988

20oct1988

25oct1988

05nov1988

10nov1988

15nov1988

20nov1988

25nov1988

05dec1988

10dec1988

15dec1988

20dec1988

25dec1988

05jan1989

10jan1989

15jan1989

20jan1989

25jan1989

;

run;

data anno_ticks; set anno_days;

length function $8 text $20;

xsys='2'; ysys='1'; when='a';

x=catch_date; y=0;

function='move'; output;

y=1.5; function='draw'; output;

run;

data anno_days; set anno_days;

length function $8 text $20;

xsys='2'; ysys='1'; when='a';

x=catch_date; y=0;

function='label'; position='e'; text=put(catch_date,day.);

run;

data anno_months;

informat catch_date date9.;

format catch_date date9.;

input catch_date;

datalines;

15oct1988

15nov1988

15dec1988

15jan1989

;

run;

data anno_months; set anno_months;

length function $8 text $20;

xsys='2'; ysys='1'; when='a';

x=catch_date; y=-7;

function='label'; position='5'; text=trim(left(put(catch_date,monname20.)));

run;

/*

Wanted the refline to be slightly to the left of the 1st of month,

therefore annotating it instead of using aurohref.

*/

data anno_ref;

informat catch_date date9.;

format catch_date date9.;

input catch_date;

datalines;

01nov1988

01dec1988

01jan1989

;

run;

data anno_ref; set anno_ref;

length function $8 text $20;

xsys='2'; ysys='1'; when='a';

x=catch_date-1;  /* shift it left a bit */

y=0;

function='move'; output;

y=100; function='draw'; output;

run;

data anno_all; set anno_ticks anno_ref anno_days anno_months;

run;

goptions device=png;

goptions noborder;

ODS LISTING CLOSE;

ODS HTML path=odsout body="&name..htm"

(title="Roe Menhaden @ Beaufort, NC")

style=htmlblue;

goptions gunit=pct htitle=4.0 ftitle="albany amt/bold" htext=2.8 ftext="albany amt/bold";

symbol1 font='albany amt/unicode' value='25cf'x height=3.5 interpol=none color=black;

axis1 label=(h=3.5 angle=90 'Fishing  Year') order=(1988 to 1999 by 1) minor=none

major=(height=-.75) offset=(5,5);

/*

Trick #3 - I force the x-axis to cross a year boundary

*/

axis2 label=none order=('01oct1988'd to '01feb1989'd by month) minor=none

major=none value=none offset=(0,0);

title1 h=1 " ";

title2 h=2 a=90 " ";

title3 h=2 a=-90 " ";

footnote1 h=5 ' ';

footnote2 j=l move=(+13,+0) font="thorndale amt/bold" h=3.0

'Figure 2. -- A scatter plot of dates when roe menhaden were landed at Beaufort,';

footnote3 j=l move=(+13,+0) font="thorndale amt/bold" h=3.0

'North Carolina, 1988-1999  ("Fishing Year" includes January of the following';

footnote4 j=l move=(+13,+0) font="thorndale amt/bold" h=3.0

'calendar year).';

footnote5 h=2 ' ';

proc gplot data=fish_data anno=anno_all;

format plot_date date9.;

plot fishing_year*plot_date=1 /

vaxis=axis1

haxis=axis2

des='' name="&name";

run;

quit;

ODS HTML CLOSE;

ODS LISTING;

View solution in original post

4 REPLIES 4
Jay54
Meteorite | Level 14

If it is important to retain the scale for the days along the X axis, then I suggest use SGPLOT procedure, with DAYn. format for X variable.  You can draw reflines at each month end for the separators.  With SAS 9.3, you can add the month names using SGAnnotate.

If scale for the dates on x axis is not critical, you could use the SGPANEL procedure.  Extract monthname as a separate column and use it as the PANELBY variable with LAYOUT=COLUMNLATTICE, and ColumnHeaderPosition=bottom.  Use a SCATTER plot with X=date with DAYn. format.

With SGPANEL solution, you may get data range in each column only to the extend you have data, and each cell will be of equal width.  To force the dates in each column to span 1-30 (or 28 or 31), you could use try using another column that has data for those dates, and use that as a scatter ovarlay with markersize=0.  I think that may force the correct dates on each axis.

If you are having problems, attach your data, and I can try it out.

mfisher
Fluorite | Level 6

Thanks, Sanjay.  I have your book!

GraphGuy
Meteorite | Level 14

Here's an alternate way, if you want to get the *exact* same plot.  I use a custom Gplot, with a bit of date manipulation and a bit of annotate.  Below is the SAS/Graph output, and the code I used:

roe_menhaden_plot.png

%let name=roe_menhaden_plot;

filename odsout '.';

/*

A scatter plot of dates when roe menhaden were landed at

Beaufort, North Carolina, 1988-1999.  Using estimated data

from Figure 2 in the following paper:

http://spo.nwr.noaa.gov/mfr621/mfr6211.pdf

You can't really get this graph by default, and you have to

use a few little "tricks" ... look for 'Trick' in the comments...

*/

data fish_data;

informat catch_date date9.;

format catch_date date9.;

input catch_date;

datalines;

25oct1988

04nov1988

09nov1988

12nov1988

15nov1988

22nov1988

25nov1988

27nov1988

03dec1988

08dec1988

10dec1988

14dec1988

27dec1988

30dec1988

03jan1989

09jan1989

11jan1989

12oct1989

14oct1989

17oct1989

09nov1989

13nov1989

14nov1989

22nov1989

30nov1989

03jan1990

03nov1990

07nov1990

14nov1990

21nov1990

23nov1990

26nov1990

27nov1990

28nov1990

03dec1990

07dec1990

10dec1990

14dec1990

20dec1990

27dec1990

03jan1991

04jan1991

08jan1991

11jan1991

19jan1991

05nov1991

06nov1991

07nov1991

08nov1991

18nov1991

19nov1991

31dec1991

22jan1992

30oct1992

08nov1992

10nov1992

13nov1992

17nov1992

19nov1992

24nov1992

28nov1992

03dec1992

04dec1992

08dec1992

09dec1992

03nov1993

12nov1993

15nov1993

16nov1993

17nov1993

22nov1993

29nov1993

30nov1993

01dec1993

02dec1993

03dec1993

04dec1993

06dec1993

08dec1993

14dec1993

08nov1994

14nov1994

15nov1994

24nov1994

25nov1994

26nov1994

27nov1994

06dec1994

16nov1995

17nov1995

18nov1995

20nov1995

22nov1995

24nov1995

27nov1995

04dec1995

06dec1995

13dec1995

16dec1995

10nov1996

11nov1996

12nov1996

18nov1996

21nov1996

25nov1996

29nov1996

30nov1996

13dec1996

16dec1996

17dec1996

20jan1997

16nov1997

17nov1997

20nov1997

26nov1997

27nov1997

28nov1997

29nov1997

07dec1997

10dec1997

11dec1997

18dec1997

19dec1997

02nov1998

09nov1998

13nov1998

15nov1998

16nov1998

22nov1998

27nov1998

28nov1998

30nov1998

01dec1998

02dec1998

06dec1998

30nov1999

05dec1999

06dec1999

07dec1999

19dec1999

28dec1999

29dec1999

30dec1999

31dec1999

;

run;

data fish_data; set fish_data;

day=.; day=trim(left(put(catch_date,day.)));

month_name=trim(left(put(catch_date,monname20.)));

year=.; year=trim(left(put(catch_date,year4.)));

if month_name='January' then fishing_year=year-1;

else fishing_year=year;

/*

Trick #1 ... I'm converting the catch_date to a 1988 date,

so they can all be plotted along the same x-axis.

*/

plot_date=catch_date-((fishing_year-1988)*365.25);

run;

/*

Trick #2 - I annotate the tickmarks, and dates & months,

along the x-axis, so I can get them exactly the way I want.

*/

data anno_days;

informat catch_date date9.;

format catch_date date9.;

input catch_date;

datalines;

05oct1988

10oct1988

15oct1988

20oct1988

25oct1988

05nov1988

10nov1988

15nov1988

20nov1988

25nov1988

05dec1988

10dec1988

15dec1988

20dec1988

25dec1988

05jan1989

10jan1989

15jan1989

20jan1989

25jan1989

;

run;

data anno_ticks; set anno_days;

length function $8 text $20;

xsys='2'; ysys='1'; when='a';

x=catch_date; y=0;

function='move'; output;

y=1.5; function='draw'; output;

run;

data anno_days; set anno_days;

length function $8 text $20;

xsys='2'; ysys='1'; when='a';

x=catch_date; y=0;

function='label'; position='e'; text=put(catch_date,day.);

run;

data anno_months;

informat catch_date date9.;

format catch_date date9.;

input catch_date;

datalines;

15oct1988

15nov1988

15dec1988

15jan1989

;

run;

data anno_months; set anno_months;

length function $8 text $20;

xsys='2'; ysys='1'; when='a';

x=catch_date; y=-7;

function='label'; position='5'; text=trim(left(put(catch_date,monname20.)));

run;

/*

Wanted the refline to be slightly to the left of the 1st of month,

therefore annotating it instead of using aurohref.

*/

data anno_ref;

informat catch_date date9.;

format catch_date date9.;

input catch_date;

datalines;

01nov1988

01dec1988

01jan1989

;

run;

data anno_ref; set anno_ref;

length function $8 text $20;

xsys='2'; ysys='1'; when='a';

x=catch_date-1;  /* shift it left a bit */

y=0;

function='move'; output;

y=100; function='draw'; output;

run;

data anno_all; set anno_ticks anno_ref anno_days anno_months;

run;

goptions device=png;

goptions noborder;

ODS LISTING CLOSE;

ODS HTML path=odsout body="&name..htm"

(title="Roe Menhaden @ Beaufort, NC")

style=htmlblue;

goptions gunit=pct htitle=4.0 ftitle="albany amt/bold" htext=2.8 ftext="albany amt/bold";

symbol1 font='albany amt/unicode' value='25cf'x height=3.5 interpol=none color=black;

axis1 label=(h=3.5 angle=90 'Fishing  Year') order=(1988 to 1999 by 1) minor=none

major=(height=-.75) offset=(5,5);

/*

Trick #3 - I force the x-axis to cross a year boundary

*/

axis2 label=none order=('01oct1988'd to '01feb1989'd by month) minor=none

major=none value=none offset=(0,0);

title1 h=1 " ";

title2 h=2 a=90 " ";

title3 h=2 a=-90 " ";

footnote1 h=5 ' ';

footnote2 j=l move=(+13,+0) font="thorndale amt/bold" h=3.0

'Figure 2. -- A scatter plot of dates when roe menhaden were landed at Beaufort,';

footnote3 j=l move=(+13,+0) font="thorndale amt/bold" h=3.0

'North Carolina, 1988-1999  ("Fishing Year" includes January of the following';

footnote4 j=l move=(+13,+0) font="thorndale amt/bold" h=3.0

'calendar year).';

footnote5 h=2 ' ';

proc gplot data=fish_data anno=anno_all;

format plot_date date9.;

plot fishing_year*plot_date=1 /

vaxis=axis1

haxis=axis2

des='' name="&name";

run;

quit;

ODS HTML CLOSE;

ODS LISTING;

mfisher
Fluorite | Level 6

Wow!  Thanks!

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 3002 views
  • 0 likes
  • 3 in conversation