BookmarkSubscribeRSS Feed

What's the rationale for not having a standalone ODS destination? It's pretty common that I only want to export graphic files. It doesn't really make sense that the way to do that is to open up the LISTINGS destination, the destination for producing fixed-width text output. I know that works, but when I step out of my perspective of a long-time SAS programmer, it's just plain weird to do it that way.

 

Or to put it another way. I regularly teach an undergrad SAS programming class, and utilize the Programming 1 and Programming 2 materials. So this use case isn't directly covered, but I can certainly imagine a student asking "is there a way to just export graphs?" If the WHY question came up, how much would that reinforce to budding statisticians/data scientists any preconceived notions about SAS? 

 

Wouldn't it be nice to have a GRAPHICS or GRAPHICSONLY destination, and maybe have some options that would be handy for that purpose? It's almost crazy to me that this has never been created. 

10 Comments
Quentin
Super User

That's interesting.  I think most of the modern SAS IDEs (e.g. EG, studio, etc) pretty much assume that you have one destination turned on (typically HTML).  So I don't think a user would have to turn on the listing destination just to get a png file or whatever.  Wouldn't they just code something like:

 

ods html gpath="Q:\junk";
ods graphics on / imagefmt=png imagename="MyGraph" ;

proc sgplot data=sashelp.class;
    scatter x=height y=weight;
run;

?

 

But I can see how to a student, having ODS graphics destination (with options for PNG/JPG/SVG etc) might be a more obvious implementation.

 

With the current code, I think the easier change might be to add an imagepath option to the ODS GRAPHICS statement.

 

The good thing is with AI code assistants, students should be much faster at figuring how to do something in SAS. Much faster than reading through paper manuals or posting on SAS-L, back in my day, walking up a hill in the snow both ways to get to school...

 

Statsbob
Fluorite | Level 6

ods html opens a new destination and you must specify a file (well I would being on a managed computer). I don't want to create another report file. I just want to save the graphs for what I'm working on to a location.

 

The default in EG is SASREPORT I think, but I don't know that you can add commands to set gpath. (I've never had any luck anyway)

Quentin
Super User

How odd.  I tried over-riding GPATH for the ODS HTML5 statement generated by EG, but had no luck.  Maybe I'm doing something dumb?  Seems like it should be easy.  

 

7         FILENAME EGHTML TEMP;
18         ODS HTML5(ID=EGHTML) FILE=EGHTML
19             OPTIONS(BITMAP_MODE='INLINE')
20             %HTML5AccessibleGraphSupported
21             ENCODING='utf-8'
22             STYLE=HTMLBlue
23             NOGTITLE
24             NOGFOOTNOTE
25             GPATH=&sasworklocation
26         ;
NOTE: Writing HTML5(EGHTML) Body file: EGHTML
27         
28         *add gpath ;
29         ods HTML5(ID=EGHTML) gpath="~";
30         
31         ods graphics on / imagefmt=png imagename="MyGraph" ;
32         
33         proc sgplot data=sashelp.class;
34             scatter x=height y=weight;
35         run;

NOTE: PROCEDURE SGPLOT used (Total process time):
      real time           0.09 seconds
      cpu time            0.04 seconds
      
NOTE: There were 19 observations read from the data set SASHELP.CLASS.

Code runs without errors, but no .png file created.  

 

Like you said, if I add ODS listing statement, it works fine: 

29         ods listing gpath="~";
30         
31         ods graphics on / imagefmt=png imagename="MyGraph" ;
32         
33         proc sgplot data=sashelp.class;
34             scatter x=height y=weight;
35         run;

NOTE: PROCEDURE SGPLOT used (Total process time):
      real time           0.13 seconds
      cpu time            0.06 seconds
      
NOTE: Listing image output written to /home/Quentin/MyGraph9.png.
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
PaigeMiller
Diamond | Level 26

I feel like I am missing something. The following code, using HTML, creates the plots as .png files in whatever folder you specify.

 

ods html path="C:\Users\xxxxxx\Documents\temp1" gpath="C:\Users\xxxxxx\Documents\temp1";
proc sgplot data=sashelp.class;
    scatter x=height y=weight;
run;
proc sgplot data=sashelp.class;
    vbar age/response=height;
run;
ods html close;

PaigeMiller_0-1787596602698.png

 

Quentin
Super User

I found this blog post by @ChrisHemedinger : https://blogs.sas.com/content/sasdummy/2015/11/23/ods-statement-options-to-change/

 

For a minute I thought again that I could do it with:

ODS HTML5 (ID=EGHTML) gpath="~";
ods graphics on / imagefmt=png imagename="MyGraph" ;

proc sgplot data=sashelp.class;
    scatter x=height y=weight;
run;

But it looks like you are not able to change the value for gpath after opening a destination, as he notes in the blog for the path option.  Maybe Chris will have another idea.

 

I also tried forcing the issue by closing and reopening just the HTML5 destination, but still couldn't make it work:

ODS _ALL_ CLOSE;

ODS HTML5 FILE="%sysfunc(pathname(work))/foo.htm" GPATH="~" ;
ods graphics on / imagefmt=png imagename="MyGraph" ;

proc sgplot data=sashelp.class;
    scatter x=height y=weight;
run;

ods _all_ close ;

which I find confusing.

 

Quentin
Super User

Thanks @PaigeMiller, you are correct.  Works on linux too.  I was blindly following the log, which doesn't write a note about creating the .png file.  But when I looked in the directory, there were about 50 png files waiting form me from all my "failed" attempts.

 

You can do stuff like:

ods HTML path=&sasworklocation gpath='~';
proc sgplot data=sashelp.class;
    scatter x=height y=weight;
run;
proc sgplot data=sashelp.class;
    vbar age/response=height;
run;
ods html close;

 

PaigeMiller
Diamond | Level 26

&sasworklocation — is the for EG only? I don't seem to be able to use it in base SAS 9.4

Quentin
Super User

Yes, it's one of the macro vars EG makes.  I tend not to use them.  I would use  "%sysfunc(pathname(work))" for portability.  But students might find &sasworklocation easier.

Statsbob
Fluorite | Level 6

I guess the point I'm making is that this use case could use a destination so that it was intuitive to do this.

 

Yes I am capable of outputting graphics to a folder. I've done it tons of times. The easiest way is via LISTING. HTML works too but then I either need to specify file="" and make an HTML file (which I don't want) or not specify one and accept the error in the log (for my it-managed machine that doesn't grant write permissions to the default folder). You guys are SAS programmers so you're coming up with ways to get the HTML to work. 

 

Why not:

ODS GRAPHICSONLY gpath="s:/my/path";

 

There might be a better name for the destination, but wouldn't that make sense? In my SAS class that would be an easy sell. 

Quentin
Super User

Agree for ease of use for students (and me : ), I could imagine an ODS destination like:

ODS GRAPHICSONLY imagefmt=png imagename="MyGraph" gpath='~';

Or just adding a gpath option to the ODS GRAPHICS statement:

ods graphics on / imagefmt=png imagename="MyGraph" gpath='~' ;

On reflection, it's weird to me that there is no gpath option for the ODS GRAPHICS statement. It feels like that is a missing option that would be nice.

 

I rarely try to make stand-alone image files.  But when I do, I often end up doing the same dance I did today, cuz I don't remember the ODS listing trick.

 

Ooh, I have an idea @Statsbob :

 

Since your students are using EG and the SAS Report destination, you could configure EG to set gpath to their home directory.  If I do this:

 

EGoption.png

 

Then you could write graphs to your home directory with:

ods graphics on / imagefmt=png imagename="MyGraph";
proc sgplot data=sashelp.class;
    scatter x=height y=weight;
run;

This isn't the easy flexibility you want, but it could be helpful for students who just want to see the image files they create.