Data visualization with SAS programming

round round things?

Reply
Occasional Contributor
Posts: 9

round round things?

Hi all, I'm having difficulty producing graphs that display well at a high resolution. When I use the 'dot' symbol in proc gplot (most recently, but also in other procs) all my small dots look lumpy, and my large dots look like many-sided polygons. When I print out the default graph window version it actually looks better, but seems to be a raster image since the dots are all stretched when printed in portrait format. If I output via 'ods pdf' my fonts are all clearly vector, but my dots are just as bad looking and also print poorly. I haven't played too much with the goptions/device settings because I don't really understand them that well, but have looked around the web and found ways to output individual .ps files that end up looking just as bad.

What I really want is just a simple way to output graphs where round things are round, and straight things are straight. This could be either through vector or very high resolution raster images, I don't particularly care which since I don't plan on doing any image manipulation after the fact. I use all sorts of different procs, and a lot of annotate, in case that makes any difference.

-Max
SAS Super FREQ
Posts: 8,642

Re: round round things?

Hi:
The version of SAS that you are using and the DEVICE= option that you use and your ODS destination of interest would also be helpful information.

cynthia
Occasional Contributor
Posts: 9

Re: round round things?

Sorry, I'm using SAS 9.2 and usually just the default DEVICE, I just switch the ods output type (ie. 'ods pdf;' or 'ods rtf' or nothing). In the past I have tried different devices, for instance 'device=pscolor' just yesterday to no avail, but I don't really know that much about what I should be using, which is what my question is Smiley Happy

If you take this code for instance:
[pre]
goptions reset=all ;
ods pdf ;
ods rtf ;
symbol value=dot height=10 ;
proc gplot data=sashelp.class ;
plot height*weight ;
run;
symbol value=dot height=.01 ;
proc gplot data=sashelp.class ;
plot height*weight ;
run;
ods pdf close ;
ods rtf close ;
[/pre]

The default graph window output looks kind of lumpy and prints stretched out. The rtf output looks lumpy and is small as well, plus it cuts off some of one of the big dots. The pdf output is usually my best, but even there the large dots are many-sided polygons, and the small dots (upon very close inspection) seem to be a combination of either very small squares, or slightly larger rounded-corner squares with bites taken out of their upper right corners. I'm not sure what to call those, but they're clearly not 'dots'!

If I'm just printing things out to review with people for ongoing projects I don't mind that it's a little weird looking, and the pdf output is usually just fine. But I also need to output publication-quality graphics in the end, preferably in a format that a researcher can simply copy and paste into a manuscript, or submit separately along with the manuscript. These can be raster images if they're sufficiently high-resolution, or they can be vector images if SAS supports vector elements for things like 'dot's.

-Max
SAS Super FREQ
Posts: 8,642

Re: round round things?

Hi:
Well, since you are using SAS 9.2, I'd recommend taking advantage of the new font-rendering engines that are available. Without a height unit specified, I believe the default unit is the cell for the SYMBOL statement.

Personally, I prefer to use point sizes and a font like Monotype Sorts for my symbols, I think they look better, especially in 9.2.

When I run the code below, the round things look round. I picked just 2 sizes to test. You can of course, pick other sizes. Or, you could pick a different font and/or a different symbol (and a different color).

The default DEVICE= for PDF and RTF is different -- PDF uses or "likes" to use SASPRTC device by default and RTF "likes" to use SASEMF device by default. Both destinations will use the PNG device and/or the JPEG device. Or you can consult the documentation link below for other devices that they have in common. I am usually pretty happy with SASPRTC and/or SASEMF, but occasionally I get asked for PNG and I think that looks about the same. Note, in the program below, I name each file instead of taking the default, so I know when I open the file exactly WHAT device and WHAT size were used for the output file.

Some useful references:
http://support.sas.com/documentation/cdl/en/graphref/63022/HTML/default/viewer.htm#a003263978.htm
http://support.sas.com/documentation/cdl/en/graphref/63022/HTML/default/viewer.htm#a003275276.htm

cynthia
[pre]

%macro makegrf(htdot=10pt, dev=, dest=);
title;
goptions reset=all device=&dev ;
ods &dest file="c:\temp\output\diffdevice_&dev._&htdot..&dest" ;

title "Device=&dev and dot size=&htdot";
symbol h=&htdot v='6C'x font="Monotype Sorts/bold" color=cx2597FA;
proc gplot data=sashelp.class ;
plot height*weight ;
run;
quit;

ods _all_ close;
%mend makegrf;

** SASEMF is the default device for RTF;
** SASPRTC is the default device for PDF;
** If you try to use SASEMF with PDF, you will get a note;
** in the log that SASEMF is not a valid device for PDF;
** and vice versa if you try SASPRTC with RTF.;

%makegrf(htdot=8pt, dev=sasprtc, dest=pdf);
%makegrf(htdot=8pt, dev=png, dest=pdf);
%makegrf(htdot=8pt, dev=jpeg, dest=pdf);

%makegrf(htdot=8pt, dev=sasemf, dest=rtf);
%makegrf(htdot=8pt, dev=png, dest=rtf);
%makegrf(htdot=8pt, dev=jpeg, dest=rtf);

%makegrf(htdot=12pt, dev=sasprtc, dest=pdf);
%makegrf(htdot=12pt, dev=png, dest=pdf);
%makegrf(htdot=12pt, dev=jpeg, dest=pdf);

%makegrf(htdot=12pt, dev=sasemf, dest=rtf );
%makegrf(htdot=12pt, dev=png, dest=rtf);
%makegrf(htdot=12pt, dev=jpeg, dest=rtf);
[/pre]
Occasional Contributor
Posts: 9

Re: round round things?

Hi Cynthia, that's exactly what I was looking for! The default 'dot' symbol seems not to be represented well at high resolution, but characters from other fonts give me nice round symbols, thanks Smiley Happy

-Max
SAS Employee
Posts: 963

Re: round round things?

One "gotcha" to watch out for with using font characters as plot markers ... the font characters are not guaranteed to 'center' on the center of the marker. Fonts have spacing to accommodate characters of the font with descenders (such as g/y/p) and such, and they are created to look good in a word or sentence, but not necessarily to center well as a plot symbol.

Here is some code you can use to easily test out characters of different fonts, and see how they center (I think you will need 9.2 to use 'unicode' characters, as I'm using in the code below ... you should be able to use non-unicode characters in prior versions) ...


symbol1 value='25cf'x font="albany amt/unicode" height=25pt color=blue;

data foo;
x=0; y=0; output;
x=1; y=1; output;
x=2; y=2; output;
x=3; y=3; output;
x=4; y=4; output;
run;

proc gplot data=foo;
plot y*x=1 /
href=1 2 3 chref=graydd
vref=1 2 3 cvref=graydd
;
run;
Occasional Contributor
Posts: 9

Re: round round things?

Now that I'm trying to use it, I'm noticing this, and it's a big problem since I'm trying to annotate different sized dots onto a plot and even when they all share the same y-axis value, they plot at vastly different centered-y-values. If you run the following, you can clearly see each successive size increase moves the center of the "dot" further down the y-axis... I also tried a few different fonts. So I guess I'm back to square 1 then? Is there any way to plot round dots in SAS?

[pre]
symbol1 value='6C'x font="Monotype Sorts/bold" height=25pt color=blue;
data foo;
x=0; y=0; output;
x=1; y=1; output;
x=2; y=2; output;
x=3; y=3; output;
x=4; y=4; output;
run;
data anno ;
set foo ;
xsys='2' ; ysys='2' ;
function='label' ;
text='6C'x ;
style="Monotype Sorts/bold" ;
color=' red' ;
size=5*y ;
output ;
y=2.5 ;
color='green' ;
output ;
run ;
proc gplot data=foo;
plot y*x=1 /
href=1 2 3 chref=graydd
vref=1 2 3 cvref=graydd
anno=anno
;
run;
[/pre]

-Max
SAS Employee
Posts: 963

Re: round round things?

If you're wanting circular markers, I find that annotated pies (empty ones, just using the outside ring) show up smoother than gplot 'dots' in many situations (they're rendered differently). And the annotated pies are centered exactly on the specified x/y coordinate.

Here's some code, if you'd like to try it - you can control the size & color of the circles, using the size & color variables in the annotate data set...

data foo;
x=0; y=0; output;
x=1; y=1; output;
x=2; y=2; output;
x=3; y=3; output;
x=4; y=4; output;
run;

data dot_anno; set foo;
xsys='2'; ysys='2'; hsys='3'; when='a';
function='pie'; style='pempty'; color='blue'; rotate=360; size=5;
run;

symbol value=none interpol=none;
proc gplot data=foo anno=dot_anno;
plot y*x /
href=1 2 3 chref=graydd
vref=1 2 3 cvref=graydd
;
run;
Occasional Contributor
Posts: 9

Re: round round things?

The smaller pies are maybe slightly better, but also can't seem to be as small as the regular 'dot' symbols can be. The larger pies though seem to be rendered the exact same way.

[pre]
goptions reset=all ;
data foo;
x=0; y=0; output;
x=1; y=1; output;
x=2; y=2; output;
x=3; y=3; output;
x=4; y=4; output;
run;

data dot_anno; set foo;
xsys='2'; ysys='2'; hsys='3'; when='a';
function=' pie'; style='psolid'; color='blue'; rotate=360; size=5;
output ;
function='symbol'; style=' '; color=' red'; rotate=.; size=14; text='dot';
output ;
y=4-y;
function=' pie'; style='psolid'; color='blue'; rotate=360; size=.0001;
output ;
y=((y-2)*.95)+2;
function='symbol'; style=' '; color=' red'; rotate=.; size=.2; text='dot';
output ;
run;

ods pdf ;
symbol value=none interpol=none;
proc gplot data=foo anno=dot_anno;
plot y*x /
href=1 2 3 chref=graydd
vref=1 2 3 cvref=graydd
;
run;
ods pdf close ;
[pre]

-Max
Grand Advisor
Posts: 9,699

Re: round round things?

For controlling annotate values for what you're doing I suggest investigating the annotate macros %ANNOMAC and %SLICE. A bit more code but may provide more what you are looking for.
Occasional Contributor
Posts: 9

Re: round round things?

That might make the annotation datasets easier to build, but how would that help render the graphics any smoother?

-Max
Grand Advisor
Posts: 9,699

Re: round round things?

> That might make the annotation datasets easier to
> build, but how would that help render the graphics
> any smoother?
>
> -Max

Part of the issue is larger item shifting the apparent center. The SLICE would fix that part. Depending upon display, system and other factors it MAY render differently than font images, possibly reducing the not quite roundness.
Occasional Contributor
Posts: 9

Re: round round things?

>> That might make the annotation datasets easier to
>> build, but how would that help render the graphics
>> any smoother?
>>
>> -Max

> Part of the issue is larger item shifting the
> apparent center. The SLICE would fix that part.
> Depending upon display, system and other factors
> it MAY render differently than font images,
> possibly reducing the not quite roundness.

The issue with the "dot" symbols is that they aren't round, and the issue with the font images is that they don't center. The "slice" doesn't do anything that the "dot" doesn't already do more easily (they center and render exactly the same as each other), unless you want actual partial slices, which I don't.

-Max
Valued Guide
Posts: 632

Re: round round things?

You might consider building your own symbol using the GFONT procedure. You have a lot of control of the resolution and once built the symbol will be used like any other font.

Although I am unsure that this will help, it might be worth a try. Here is a bit of a code sample.
[pre]data fontdata(keep=char seg x y lp ptype);
retain char 'c'
seg 1
lp 'p';
ptype='w'; x=0; y=100; output fontdata;
ptype='v'; x=100; y=50; output fontdata;
do deg = 0 to 360 by 1;
rad = deg*arcos(-1)/180;
x=50*cos(rad)+50; y=50*sin(rad)+50; output fontdata;
end;
/* instead of 361 line segments, 4 arcs might be just as good */
/*ptype='c'; x=50; y=50; output fontdata;*/
/*ptype='v'; x=50; y=100; output fontdata;*/
/*ptype='c'; x=50; y=50; output fontdata;*/
/*ptype='v'; x=0; y=50; output fontdata;*/
/*ptype='c'; x=50; y=50; output fontdata;*/
/*ptype='v'; x=50; y=0; output fontdata;*/
/*ptype='c'; x=50; y=50; output fontdata;*/
/*ptype='v'; x=100; y=50; output fontdata;*/
run;

libname gfont0 'c:\temp';
proc gfont data=fontdata
name=mydot
filled
resolution=2;
run;

symbol1 f=mydot c=blue v='c';
proc gplot data=sashelp.class;
plot height*weight;
run;
quit;[/pre]
SAS Super FREQ
Posts: 863

Re: round round things?

Since you're using SAS 9.2, try using one of the SG procedures:

[pre]
goptions reset=all ;
ods pdf ;ods rtf ;
proc sgplot data=sashelp.class ;
scatter y=height x=weight / markerattrs=(symbol=circlefilled size=40px);
run;
proc sgplot data=sashelp.class ;
scatter y=height x=weight / markerattrs=(symbol=circlefilled size=3px);
run;
ods pdf close ;
ods rtf close ;
[/pre]

Hope this helps,
Dan
Post a Question
Discussion Stats
  • 17 replies
  • 297 views
  • 0 likes
  • 6 in conversation