Solved
Contributor
Posts: 23

# Generating coloured 3D surface plots

I want to generate a 3D surface plot eg : http://www.datavis.ca/sasmac/surface.html

I could not implement the code mentioned here.

I tried : http://support.sas.com/kb/24/861.html but the

but the grid is not filled (only has wiremesh output).

Is there an easier way to generate 3D graphs surface plots with specific colours (eg rainbow)?

Accepted Solutions
Solution
‎01-17-2017 11:44 AM
Super User
Posts: 10,497

## Re: Generating coloured 3D surface plots

When I create a data set named have from your example data and call the macro using:

%surface(data=have,x=longitude,y=latitude,z=yield);

I get the result in the attachment.

Not pretty but not just the wire frame.

Do you get any messages in the log about color assignments? What is your active ODS Style or destination? You may have something that doesn't support color such a the Journal styles.

All Replies
Super User
Posts: 10,497

## Re: Generating coloured 3D surface plots

Why could you not implement the code? Did you get any errors, if so provide them. No output? Wrong output?

It will help to provide the version of SAS you are running, the exact code you submitted and log when running that code (especially if there are errors.)

Contributor
Posts: 23

## Re: Generating coloured 3D surface plots

With the code available on : http://support.sas.com/kb/24/861.html

I can not generate filled polygons. I only get a coloured wiremesh (lines grid) output.

With the code available on : http://www.datavis.ca/sasmac/surface.html

I get the same output even when I change the data. I copy pasted the macro and tried to replace the data with my data but the output does not change. What are the steps that I should follow to get desired output using the code available on http://www.datavis.ca/sasmac/surface.html

Are there any simpler ways / alternatives to generating coloured 3D surface plots?

I would greatly appreciate your help.

I want to plot a graph for the following data:

Longitude Latitude Yield

1 1 4.017916667
2 1 4.113095238
3 1 3.838888889
4 1 .
5 1 3.864285714
6 1 4.181597222
7 1 4.279947917
8 1 4.465570175
9 1 4.446626984
10 1 4.545643939
11 1 4.624583333
12 1 4.542763158
13 1 4.408991228
14 1 4.481359649
15 1 4.378472222
16 1 4.220343137
17 1 4.288235294
18 1 4.173529412
19 1 4.085185185
20 1 4.075925926
21 1 4.079960317
22 1 4.110416667
23 1 4.167613636
24 1 4.155324074
25 1 4.208055556
1 2 3.915625
2 2 3.931818182
3 2 3.736666667
4 2 3.739166667
5 2 3.788958333
6 2 4.006302083
7 2 4.130307018
8 2 4.311022727
9 2 4.333368056
10 2 4.459722222
11 2 4.521376812
12 2 4.465398551
13 2 4.341123188
14 2 4.415036232
15 2 4.327840909
16 2 4.222291667
17 2 4.290740741
18 2 4.215625
19 2 3.989583333
20 2 4.0125
21 2 4.002083333
22 2 4.070394737
23 2 4.098015873
24 2 4.143981481
25 2 4.158888889
1 3 4.005989583
2 3 3.970555556
3 3 3.776923077
4 3 3.819642857
5 3 3.871722222
6 3 3.967175926
7 3 4.061447368
8 3 4.276931818
9 3 4.257644928
10 3 4.397101449
11 3 4.507539683
12 3 4.49781746
13 3 4.31547619
14 3 4.498412698
15 3 4.499166667
16 3 4.388596491
17 3 4.470833333
18 3 4.442222222
19 3 4.142222222
20 3 4.054444444
21 3 4.019362745
22 3 4.10372807
23 3 4.154960317
24 3 4.189692982
25 3 4.24877451
1 4 3.890416667
2 4 3.894791667
3 4 3.756617647
4 4 3.794852941
5 4 3.807864583
6 4 3.970147059
7 4 4.064114583
8 4 4.27087963
9 4 4.254212963
10 4 4.424537037
11 4 4.370833333
12 4 4.33203125
13 4 4.078645833
14 4 4.220833333
15 4 4.236666667
16 4 4.189285714
17 4 4.247569444
18 4 4.29
19 4 3.99
20 4 3.886363636
21 4 3.903571429
22 4 4.057843137
23 4 4.150833333
24 4 4.187719298
25 4 4.240686275
1 5 3.856578947
2 5 3.781547619
3 5 3.685416667
4 5 3.692361111
5 5 3.684427083
6 5 3.740677083
7 5 3.86224359
8 5 4.039940476
9 5 4.073869048
10 5 4.334615385
11 5 4.341666667
12 5 4.264772727
13 5 3.95530303
14 5 4.021212121
15 5 3.9325
16 5 3.958333333
17 5 4.095833333
18 5 .
19 5 .
20 5 3.903125
21 5 3.960416667
22 5 4.022395833
23 5 4.128508772
24 5 4.14375
25 5 4.197058824
1 6 3.922794118
2 6 3.844078947
3 6 3.79921875
4 6 3.808611111
5 6 3.830833333
6 6 3.731893939
7 6 3.763645833
8 6 3.83712963
9 6 3.778796296
10 6 3.880208333
11 6 3.882142857
12 6 4.063095238
13 6 3.941071429
14 6 4.182738095
15 6 4.286309524
16 6 4.384027778
17 6 .
18 6 .
19 6 .
20 6 4.03125
21 6 4.060416667
22 6 4.180989583
23 6 4.261458333
24 6 4.321428571
25 6 4.370833333
1 7 3.957440476
2 7 3.844010417
3 7 3.798397436
4 7 3.843402778
5 7 3.873333333
6 7 3.705952381
7 7 .
8 7 .
9 7 .
10 7 .
11 7 .
12 7 .
13 7 .
14 7 .
15 7 .
16 7 4.292361111
17 7 4.461111111
18 7 4.388194444
19 7 4.59047619
20 7 4.427272727
21 7 4.301666667
22 7 4.35
23 7 4.439583333
24 7 4.444384058
25 7 4.466458333
1 8 3.81780303
2 8 3.761217949
3 8 3.706597222
4 8 3.685648148
5 8 3.64047619
6 8 .
7 8 .
8 8 .
9 8 .
10 8 .
11 8 .
12 8 .
13 8 .
14 8 .
15 8 .
16 8 .
17 8 .
18 8 .
19 8 4.5125
20 8 4.447569444
21 8 4.302864583
22 8 4.302083333
23 8 4.398611111
24 8 4.423484848
25 8 4.397685185
1 9 4.084722222
2 9 3.819791667
3 9 3.714583333
4 9 3.688888889
5 9 .
6 9 .
7 9 .
8 9 .
9 9 .
10 9 .
11 9 .
12 9 .
13 9 .
14 9 .
15 9 .
16 9 4.40952381
17 9 4.4890625
18 9 4.4453125
19 9 4.582954545
20 9 4.521388889
21 9 4.419212963
22 9 4.346710526
23 9 4.393849206
24 9 4.378030303
25 9 4.343859649
1 10 .
2 10 .
3 10 3.831944444
4 10 .
5 10 .
6 10 .
7 10 .
8 10 .
9 10 .
10 10 .
11 10 .
12 10 .
13 10 .
14 10 .
15 10 .
16 10 4.258333333
17 10 4.37125
18 10 4.455113636
19 10 4.58375
20 10 4.548135965
21 10 4.497916667
22 10 4.45109127
23 10 4.453804348
24 10 4.426086957
25 10 4.388333333
1 11 .
2 11 .
3 11 .
4 11 .
5 11 .
6 11 .
7 11 .
8 11 .
9 11 .
10 11 .
11 11 .
12 11 .
13 11 .
14 11 4.201388889
15 11 4.24047619
16 11 4.23030303
17 11 4.300892857
18 11 4.448828125
19 11 4.596820175
20 11 4.60217803
21 11 4.577807971
22 11 4.530018939
23 11 4.517028986
24 11 4.428030303
25 11 4.390740741
1 12 .
2 12 .
3 12 .
4 12 .
5 12 .
6 12 .
7 12 .
8 12 .
9 12 .
10 12 .
11 12 .
12 12 .
13 12 .
14 12 4.568055556
15 12 4.554761905
16 12 4.278030303
17 12 4.266071429
18 12 4.42125
19 12 4.459143519
20 12 4.467757937
21 12 4.485890152
22 12 4.433630952
23 12 4.435119048
24 12 4.372368421
25 12 4.336111111
1 13 .
2 13 .
3 13 .
4 13 .
5 13 .
6 13 .
7 13 .
8 13 .
9 13 .
10 13 .
11 13 .
12 13 .
13 13 .
14 13 .
15 13 4.547222222
16 13 4.245833333
17 13 4.19375
18 13 4.394196429
19 13 4.373651961
20 13 4.355104167
21 13 4.362797619
22 13 4.264109848
23 13 4.21984127
24 13 4.187037037
25 13 4.15297619

;

Super User
Posts: 10,497

## Re: Generating coloured 3D surface plots

Did you find the actual Surface macro definition code. This would have code that somewhere has %macro surface (); and a %mend statement to end it. When I looked at that weblink I only see instructions to use the macro Surface but no source code.

Contributor
Posts: 23

## Re: Generating coloured 3D surface plots

The Source Code is :

``` /*-----------------------------------------------------------------*
*    Name: surface.sas                                            *
*   Title: Draw color 3D surface plot with contours in X-Y plane  *
Doc: http://www.datavis.ca/sasmac/surface.html
*-----------------------------------------------------------------*
* Original author: Russ Wolfinger                                 *
*  Author:  Michael Friendly            <friendly@yorku.ca>       *
* Created: 26 Oct 2006 09:59:00                                   *
* Revised: 26 Oct 2006 09:59:00                                   *
* Version: 1.0                                                    *
*                                                                 *
*-----------------------------------------------------------------*/
/*=
=Description:

The SURFACE macro draws a 3D color-coded surface plot, showing a contour
plot in the X-Y plane.  The result is most useful for smooth surfaces, e.g.,
for functional relations, Z=f(X,Y), bivariate density estimates computed
with PROC KDE, or with the result of PROC G3GRID.

==Method:

The surface and the contour plot are constructed using filled polygons
in Annotate datasets.  The contour is identical to the surface, with the
Z coordinate set to the constant 'floor'.

=Usage:

The SURFACE macro is defined with keyword parameters.  The X=, Y= and
Z= parameters are required.
The arguments may be listed within parentheses in any order, separated
by commas. For example:

%surface(x=temperature, y=pressure, z=yield);

==Parameters:

* DATA=       The name of the input data set [Default: DATA=_LAST_]

* X=          X variable for plot [Default: X=X]

* Y=          Y variable for plot [Default: Y=Y]

* Z=          Z variable for plot [Default: Z=Z]

* WHERE=      Where clause to subset the data

* COLORS=     Color scheme (HLS|HLSllss) or list of colors. COLORS=HLS generates
NLEVELS= colors varying in hue in the HLS color scheme Hhhh80FF.
COLORS=HLSllss, where llss are hex digits, generates HLS colors
with lightness ll and saturations ss.  Otherwise, COLORS= is taken
as a blank separated list of SAS colors of length NLEVELS=.
[Default: COLORS=HLS]

* NLEVELS=    Number of levels for color [Default: NLEVELS=12]

* TICKNUM=    Number of tick marks on axes.  Specify 1-3 values, for X, Y and Z. [Default: TICKNUM=5]

* DROP=       Amount to drop contour plot beneath lowest z-value, in data units. [Default: DROP=1]

* TILT=       G3D TILT= value(s): One or more numbers giving the number of degrees
to tilt the plot. [Default: TILT=75]

* ROTATE=     G3D ROTATE= value(s): One or more numbers giving the number of degrees
to rotate the plot. [Default: ROTATE=40]

* FUZZ=       Fuzz value for binning X, Y [Default: FUZZ=1E-6]

* OPTIONS=    REVERSE and/or NOGRID.  When COLORS=HLS, OPTIONS=REVERSE reverses the
assignment of colors to heights (Z= values) in the plot.

* ANNO=       Additional input annotate data set

* OUTANNO=    Output annotate data set used with G3D [Default: OUTANNO=SURFANNO]

* GOUT=       The name of the graphics catalog [Default: GOUT=GSEG]

* NAME=       The name of the graph in the graphic catalog [Default: NAME=SURFACE]

=Example:

*-- Generate bivariate normal data;
data bivar;
do i = 1 to 10000;
x = rannor(2140);
y = -x + 3* rannor(2140);
output;
end;
run;

*-- Do bivariate density estimation;
proc kde data=bivar out=kdeout;
var x y;
run;

%include macros(surface);
%surface(data=kdeout, x=x, y=y, z=density,
where=-3<x<3)

=*/

/*---
Title: Draw color 3D surface plot with contours in X-Y plane

macro to draw color surface plot with contours underneath,
code modified from Example 6 in SAS/GRAPH Examples book,
version 6, supported by Russ Wolfinger (sasrdw@unx.sas.com)---
---*/

%macro surface(
data=,             /* name of input data set */
x=x,               /* X variable for plot                                */
y=y,               /* Y variable for plot                                */
z=z,               /* Z variable for plot                                */
where=,            /* where clause to subset the data                    */
colors=HLS,        /* color scheme (HLS) or list of colors               */
nlevels=12,        /* number of levels for color                         */
ticknum=5,         /* number of tick marks on axes                       */
drop=1,            /* amount to drop contour plot beneath lowest z-value */
tilt=75,           /* G3D TILT= value                                    */
rotate=40,         /* G3D ROTATE= value                                  */
scatopt=,          /* Any other options for the G3D SCATTER stmt         */
fuzz=1e-6,         /* fuzz value for binning X, Y                        */
options=,          /* REVERSE and/or NOGRID                              */
anno=,             /* additional input annotate data set                 */
outanno=surfanno,  /* output annotate data set used with G3D             */
gout=gseg,         /* name of output graphic catalog                     */
name=surface       /* name of graphic catalog entry                      */
);

/*---default data set---*/
%if %bquote(&data)= %then %let data=&syslast;

%local me; %let me=&sysmacroname;
%if (%length(&x)=0 or %length(&y)=0 or %length(&z)=0 )
%then %do;
%put ERROR: (&me) You must supply X=, Y= and Z= variable names;
%goto DONE;
%end;

%let options = %qupcase(&options);

%*-- Parse COLORS=HLS or COLORS=HLSllss;
%let colors  = %qupcase(&colors);
%if %substr(&colors,1,3) = HLS %then %do;
%if %length(&colors) = 3
%then %let llss=80FF;
%else %let llss=%substr(&colors,4);
%let colors=HLS;
%end;

%let xtick = %scan(&ticknum &ticknum &ticknum, 1);
%let ytick = %scan(&ticknum &ticknum &ticknum, 2);
%let ztick = %scan(&ticknum &ticknum &ticknum, 3);

options nonotes;
/*---compute ranges for the three coordinates---*/
proc means data=&data noprint min max;
%if %length(&where) %then %do;
where &where;
%end;
var &x &y &z;
output out=_range
min=xmin ymin zmin
max=xmax ymax zmax;
run;

/*---set up macro variables for the ranges---*/
%local xmin xmax ymin ymax zmin zmax floor ceil zstep;
data _null_;
set _range;
call symput('xmin', put(xmin,best.));
call symput('xmax', put(xmax,best.));
call symput('ymin', put(ymin,best.));
call symput('ymax', put(ymax,best.));
call symput('zmin', put(zmin,best.));
call symput('zmax', put(zmax,best.));
zrange = zmax - zmin;
call symput('floor',put((zmin-(&drop)*zrange),best.));
call symput('ceil',put(zmax,best.));
call symput('zstep',put(zrange/&nlevels,best.));
run;

/*---determine step sizes for x and y---*/
proc sort data=&data out=_xgrid nodupkey;
by &x;
run;

data _xgrid;
set _xgrid;
keep &x xstep;
xstep = &x - lag(&x);
if (_n_ = 2) then do;
call symput('xstep',put(xstep,best.));
end;
run;

proc sort data=&data out=_ygrid nodupkey;
by &y;
run;

data _ygrid;
set _ygrid;
keep &y ystep;
ystep = &y - lag(&y);
if (_n_ = 2) then do;
call symput('ystep',put(ystep,best.));
end;
run;

data _null_;
set _ygrid nobs=count;
call symput('ny',put(count,best.));
run;

%*-- Nested macro for color computation;
%macro surcolor(arg);
%if &colors = HLS %then %do;
length hue \$3;
%if %index(&options,REVERSE) %then %do;
deg = round((&arg)*320,2) + 120;
%end;
%else %do;
deg = 440 - round((&arg)*320,2);
%end;
hue = put(deg,\$hex3.);
color = 'H'||hue||"&llss";
drop hue;
%end;
%else %do;
color = scan("&colors", ncol);
%end;
%mend;

/*---create annotate data set for legend---*/
data _legend;
length function color \$ 8;
retain xsys ysys zsys '2';
drop legend ncol;
do legend = &zmin to (&zmax-&zstep) by &zstep;
x = &xmin;
y = &ymax;
z = legend;
function = 'poly';
style = 'solid';
ncol = min(&nlevels,int(1+(legend+(&zstep/2)-&zmin)/&zstep));
%surcolor(ncol/&nlevels);
/*
%if &colors=HLS %then %do;
%if %index(&options,REVERSE) %then %do;
deg = round((ncol/&nlevels)*320,2) + 120;
%end;
%else %do;
deg = 440 - round((ncol/&nlevels)*320,2);
%end;
hue = put(deg,\$hex3.);
color = 'H'||hue||"&llss";
%end;
%else %do;
color = scan(&colors, ncol);
%end;
*/
output;
z = legend + &zstep;
function = 'polycont';
%if not %index(&options,NOGRID) %then %do;
color = 'black';
%end;
output;
x = &xmin + (&xmax-&xmin)*.05;
output;
z = legend;
output;
end;
run;

/*---create annotate data sets for plane and surface; sort by
the sum of coordinates so graphs will be drawn from
back to front---*/
data _zval;
set &data;
%if %length(&where) %then %do;
where &where;
%end;
x = &x;
y = &y;
z = &z;
keep x y z;
run;

proc sort data=_zval;
by x y;
run;

data _surface;
set &data;
%if %length(&where) %then %do;
where &where;
%end;
sum = (&x - &xmin)/&xstep + (&y - &ymin)/&ystep;
keep &x &y &z sum;
run;

proc sort data=_surface;
by descending sum;
run;

/*---draw 4-sided polygons counter-clockwise---*/
data _surface;
set _surface;
length function color \$ 8;
retain xsys ysys zsys '2';
/* drop &x &y &z; */
x = &x;
y = &y;
if (abs(x-&xmin) < &fuzz*&xstep) or
(abs(y-&ymin) < &fuzz*&ystep) then delete;
function = 'poly';
style = 'solid';
%*surcolor;
ncol=min(&nlevels,int(1+(&z-&zmin+&fuzz*&zstep)/&zstep));
%surcolor((&z-&zmin+&fuzz*&zstep)/&zstep/&nlevels);

/*
%if &colors=HLS %then %do;
%if %index(&options,REVERSE) %then %do;
deg = round(((&z-&zmin+&fuzz*&zstep)/&zstep/&nlevels)*320,2) + 120;
%end;
%else %do;
deg = 440 - round(((&z-&zmin+&fuzz*&zstep)/&zstep/&nlevels)* 320,2);
%end;
hue = put(deg,\$hex3.);
color = 'H'||hue||'80FF';
%end;
%else %do;
color = scan("&colors", ncol);
%end;
*/
when = 'A';
idx = &ny*(x-&xmin+&fuzz*&xstep)/(&xstep) +
(y-&ymin+&fuzz*&ystep)/(&ystep) + 1;
index = idx;
set _zval point=idx;
output;
function = 'polycont';
%if not %index(&options,NOGRID) %then %do;
color = 'black';
%end;
x = x - &xstep;
idx = &ny*(x-&xmin+&fuzz*&xstep)/(&xstep) +
(y-&ymin+&fuzz*&ystep)/(&ystep) + 1;
index = idx;
set _zval point=idx;
output;
y = y - &ystep;
idx = &ny*(x-&xmin+&fuzz*&xstep)/(&xstep) +
(y-&ymin+&fuzz*&ystep)/(&ystep) + 1;
index = idx;
set _zval point=idx;
output;
x = x + &xstep;
idx = &ny*(x-&xmin+&fuzz*&xstep)/(&xstep) +
(y-&ymin+&fuzz*&ystep)/(&ystep) + 1;
index = idx;
set _zval point=idx;
output;
run;

options notes;
data _plane;
set _surface;
z = &floor;
run;

/*---merge annotate data sets---*/
data &outanno;
set _legend _plane _surface &anno;
run;

/*---create input data set for PROC G3D---*/
data _plot;
&x = &xmin;
&y = &ymin;
&z = &floor;
output;
&x = &xmax;
&y = &ymax;
output;
run;

/*---draw the surface and contours---*/
proc g3d data=_plot gout=&gout ;
scatter &y*&x=&z  /
%if %length(&rotate) %then %do;
rotate=&rotate %end;
%if %length(&tilt) %then %do;
tilt=&tilt %end;
xticknum=&xtick yticknum=&ytick zticknum=&ztick
shape='point'
zmin=&floor zmax=&ceil
annotate=&outanno  &scatopt
name="&name" des="Surface plot of &y*&x=&z"
;
run;

*-- Clean up datasets no longer needed;
proc datasets nofs nolist nowarn library=work memtype=(data);
delete _xgrid _ygrid  _zval _range _legend _plane _surface _plot;
run; quit;

%done:

%mend surface;```

Solution
‎01-17-2017 11:44 AM
Super User
Posts: 10,497

## Re: Generating coloured 3D surface plots

When I create a data set named have from your example data and call the macro using:

%surface(data=have,x=longitude,y=latitude,z=yield);

I get the result in the attachment.

Not pretty but not just the wire frame.

Do you get any messages in the log about color assignments? What is your active ODS Style or destination? You may have something that doesn't support color such a the Journal styles.

SAS Super FREQ
Posts: 896

## Re: Generating coloured 3D surface plots

You can also use GTL to render the surface:

``````proc template;
define statgraph surface;
begingraph;
entrytitle 'Yield Data';
layout overlay3d;
surfaceplotparm x=Latitude y=Longitude z=yield / surfacetype=fillgrid colorresponse=yield
colormodel=(green yellow red);
endlayout;
endgraph;
end;
run;

ods graphics / width=640px height=640px;
proc sgrender data=surface_data template=surface;
run;
``````

Contributor
Posts: 23

## Re: Generating coloured 3D surface plots

Thanks DanH

Is there a way to keep the colour scale constant for several graphs.

Can we smoothen the surface and

Can we have more than three colours?

SAS Super FREQ
Posts: 896

## Re: Generating coloured 3D surface plots

Yes... on all counts :-)

FIrst look at the code:

``````proc template;
define statgraph surface;
begingraph;
entrytitle 'Yield Data';
rangeattrmap name="yield_map";
range 3.0-5.0 / rangecolormodel=(green yellow red purple);
endrangeattrmap;
rangeattrvar attrvar=yieldvar var=yield attrmap="yield_map";
layout overlay3d;
surfaceplotparm x=Latitude y=Longitude z=yield / surfacetype=fillgrid
colorresponse=yieldvar name="surface";
continuouslegend "surface";
endlayout;
endgraph;
end;
run;

ods graphics / width=640px height=640px;
proc g3grid data=surface_data out=gridded;
grid Longitude*Latitude=Yield / spline
axis1=0 to 25 by 5
axis2=0 to 15 by 2.5;
run;
proc sort data=gridded; by Longitude Latitude; run;

proc sgrender data=gridded template=surface;
run;
``````

The RANGEATTRMAP is defining a mapping where the yields between 3.0 and 5.0 are mapped to a smooth gradient between four colors (you could add more). You could also break down this mapping such that specific ranges get a specific color (see the RANGEATTRMAP documentation). This mapping will give you your consistent colors from one run to the next. Tweak this to your specific needs.

The smoothing of the surface data is done using PROC G3GRID.

Hope this helps!

Dan

Contributor
Posts: 23

## Re: Generating coloured 3D surface plots

Thanks DanH,

The code works, but the aspect ratio of the longitude and latitude is not maintained, it appears square instead of a rectangular block (of 25 * 13 : longitude * latitude).

Also the result is a mirror image of what is expected, should I reverse the axis in my raw data?

My code is as below, and output is attached.

Thank you again for the time.

Data surface_data;
input longitude latitude yield;
datalines;
1 1 4.017916667
2 1 4.113095238
3 1 3.838888889
4 1 .
5 1 3.864285714
6 1 4.181597222
7 1 4.279947917
8 1 4.465570175
9 1 4.446626984
10 1 4.545643939
11 1 4.624583333
12 1 4.542763158
13 1 4.408991228
14 1 4.481359649
15 1 4.378472222
16 1 4.220343137
17 1 4.288235294
18 1 4.173529412
19 1 4.085185185
20 1 4.075925926
21 1 4.079960317
22 1 4.110416667
23 1 4.167613636
24 1 4.155324074
25 1 4.208055556
1 2 3.915625
2 2 3.931818182
3 2 3.736666667
4 2 3.739166667
5 2 3.788958333
6 2 4.006302083
7 2 4.130307018
8 2 4.311022727
9 2 4.333368056
10 2 4.459722222
11 2 4.521376812
12 2 4.465398551
13 2 4.341123188
14 2 4.415036232
15 2 4.327840909
16 2 4.222291667
17 2 4.290740741
18 2 4.215625
19 2 3.989583333
20 2 4.0125
21 2 4.002083333
22 2 4.070394737
23 2 4.098015873
24 2 4.143981481
25 2 4.158888889
1 3 4.005989583
2 3 3.970555556
3 3 3.776923077
4 3 3.819642857
5 3 3.871722222
6 3 3.967175926
7 3 4.061447368
8 3 4.276931818
9 3 4.257644928
10 3 4.397101449
11 3 4.507539683
12 3 4.49781746
13 3 4.31547619
14 3 4.498412698
15 3 4.499166667
16 3 4.388596491
17 3 4.470833333
18 3 4.442222222
19 3 4.142222222
20 3 4.054444444
21 3 4.019362745
22 3 4.10372807
23 3 4.154960317
24 3 4.189692982
25 3 4.24877451
1 4 3.890416667
2 4 3.894791667
3 4 3.756617647
4 4 3.794852941
5 4 3.807864583
6 4 3.970147059
7 4 4.064114583
8 4 4.27087963
9 4 4.254212963
10 4 4.424537037
11 4 4.370833333
12 4 4.33203125
13 4 4.078645833
14 4 4.220833333
15 4 4.236666667
16 4 4.189285714
17 4 4.247569444
18 4 4.29
19 4 3.99
20 4 3.886363636
21 4 3.903571429
22 4 4.057843137
23 4 4.150833333
24 4 4.187719298
25 4 4.240686275
1 5 3.856578947
2 5 3.781547619
3 5 3.685416667
4 5 3.692361111
5 5 3.684427083
6 5 3.740677083
7 5 3.86224359
8 5 4.039940476
9 5 4.073869048
10 5 4.334615385
11 5 4.341666667
12 5 4.264772727
13 5 3.95530303
14 5 4.021212121
15 5 3.9325
16 5 3.958333333
17 5 4.095833333
18 5 .
19 5 .
20 5 3.903125
21 5 3.960416667
22 5 4.022395833
23 5 4.128508772
24 5 4.14375
25 5 4.197058824
1 6 3.922794118
2 6 3.844078947
3 6 3.79921875
4 6 3.808611111
5 6 3.830833333
6 6 3.731893939
7 6 3.763645833
8 6 3.83712963
9 6 3.778796296
10 6 3.880208333
11 6 3.882142857
12 6 4.063095238
13 6 3.941071429
14 6 4.182738095
15 6 4.286309524
16 6 4.384027778
17 6 .
18 6 .
19 6 .
20 6 4.03125
21 6 4.060416667
22 6 4.180989583
23 6 4.261458333
24 6 4.321428571
25 6 4.370833333
1 7 3.957440476
2 7 3.844010417
3 7 3.798397436
4 7 3.843402778
5 7 3.873333333
6 7 3.705952381
7 7 .
8 7 .
9 7 .
10 7 .
11 7 .
12 7 .
13 7 .
14 7 .
15 7 .
16 7 4.292361111
17 7 4.461111111
18 7 4.388194444
19 7 4.59047619
20 7 4.427272727
21 7 4.301666667
22 7 4.35
23 7 4.439583333
24 7 4.444384058
25 7 4.466458333
1 8 3.81780303
2 8 3.761217949
3 8 3.706597222
4 8 3.685648148
5 8 3.64047619
6 8 .
7 8 .
8 8 .
9 8 .
10 8 .
11 8 .
12 8 .
13 8 .
14 8 .
15 8 .
16 8 .
17 8 .
18 8 .
19 8 4.5125
20 8 4.447569444
21 8 4.302864583
22 8 4.302083333
23 8 4.398611111
24 8 4.423484848
25 8 4.397685185
1 9 4.084722222
2 9 3.819791667
3 9 3.714583333
4 9 3.688888889
5 9 .
6 9 .
7 9 .
8 9 .
9 9 .
10 9 .
11 9 .
12 9 .
13 9 .
14 9 .
15 9 .
16 9 4.40952381
17 9 4.4890625
18 9 4.4453125
19 9 4.582954545
20 9 4.521388889
21 9 4.419212963
22 9 4.346710526
23 9 4.393849206
24 9 4.378030303
25 9 4.343859649
1 10 .
2 10 .
3 10 3.831944444
4 10 .
5 10 .
6 10 .
7 10 .
8 10 .
9 10 .
10 10 .
11 10 .
12 10 .
13 10 .
14 10 .
15 10 .
16 10 4.258333333
17 10 4.37125
18 10 4.455113636
19 10 4.58375
20 10 4.548135965
21 10 4.497916667
22 10 4.45109127
23 10 4.453804348
24 10 4.426086957
25 10 4.388333333
1 11 .
2 11 .
3 11 .
4 11 .
5 11 .
6 11 .
7 11 .
8 11 .
9 11 .
10 11 .
11 11 .
12 11 .
13 11 .
14 11 4.201388889
15 11 4.24047619
16 11 4.23030303
17 11 4.300892857
18 11 4.448828125
19 11 4.596820175
20 11 4.60217803
21 11 4.577807971
22 11 4.530018939
23 11 4.517028986
24 11 4.428030303
25 11 4.390740741
1 12 .
2 12 .
3 12 .
4 12 .
5 12 .
6 12 .
7 12 .
8 12 .
9 12 .
10 12 .
11 12 .
12 12 .
13 12 .
14 12 4.568055556
15 12 4.554761905
16 12 4.278030303
17 12 4.266071429
18 12 4.42125
19 12 4.459143519
20 12 4.467757937
21 12 4.485890152
22 12 4.433630952
23 12 4.435119048
24 12 4.372368421
25 12 4.336111111
1 13 .
2 13 .
3 13 .
4 13 .
5 13 .
6 13 .
7 13 .
8 13 .
9 13 .
10 13 .
11 13 .
12 13 .
13 13 .
14 13 .
15 13 4.547222222
16 13 4.245833333
17 13 4.19375
18 13 4.394196429
19 13 4.373651961
20 13 4.355104167
21 13 4.362797619
22 13 4.264109848
23 13 4.21984127
24 13 4.187037037
25 13 4.15297619

;

proc template;
define statgraph surface;
begingraph;
entrytitle 'Yield Data';
rangeattrmap name="yield_map";
range 0-3.59/ rangecolormodel=(black);
range 3.6-4.6 / rangecolormodel=(green yellow red);
endrangeattrmap;
rangeattrvar attrvar=yieldvar var=yield attrmap="yield_map";
layout overlay3d / rotate=45 tilt=50;
surfaceplotparm x=Latitude y=Longitude z=yield / surfacetype=fillgrid
colorresponse=yieldvar name="surface";
continuouslegend "surface";
endlayout;
endgraph;
end;
run;

ods graphics / width=640px height=640px;
proc g3grid data=surface_data out=gridded;
grid Longitude*Latitude=Yield / spline
axis1=0 to 25 by 1
axis2=0 to 13 by 1;
run;
proc sort data=gridded; by Longitude Latitude; run;

proc sgrender data=gridded template=surface;
run;

Contributor
Posts: 23

## Re: Generating coloured 3D surface plots

The output looks like a cube, the data is, however cuboid. The length of the 3d plot is reduced to match the width making the graph look square. Is there a way to correct this to a rectangular surface plot.

Contributor
Posts: 23

## Re: Generating coloured 3D surface plots

Thanks Ballard.... this is amazing,

The graph is quite close to what I want.

Did you only change "%surface(data=have,x=longitude,y=latitude,z=yield);" in the code?

I want to make several graphs keeping the colour scale values constant; I am not sure which part of the code should be changed.

Also can we smoothen the surface to make it look better (something similar to the surface plot shown in the link : https://support.sas.com/rnd/datavisualization/yourGraphs/technologies/Java.html (or http://tex.stackexchange.com/questions/39889/tikz-how-to-get-a-few-smooth-grid-lines-for-surface-plo...

Super User
Posts: 10,497

## Re: Generating coloured 3D surface plots

amrit11 wrote:

The graph is quite close to what I want.

Did you only change "%surface(data=have,x=longitude,y=latitude,z=yield);" in the code?

You didn't show the code you actually ran but the general use of a macro requires "compiling" the macro code by executing the code from the %macro statement to the corresponding %mend. Then Call the macro using the macro name with a percent sign: %surface.

I suspecth you may not have quite understood how to use the parameters to indicate the data set and variables. The parameter followed by equal sign is referred to as KEYWORD parameter which has the advantage of not requiring a specific order.

%surface(data=have,z=yield,x=longitude,y=latitude);

would work exactly the same. Also the author of a macro can specify default values for those that don't change very often.

SAS Super FREQ
Posts: 3,476

## Re: Generating coloured 3D surface plots

Sewe the article "Create a surface plot in SAS" for an example and discussion.

Contributor
Posts: 23

## Re: Generating coloured 3D surface plots

Yes but are the colour options not limited beyond threecolouramp. I want to make several graphs based on fixed colour values.

Thank you Rick

☑ This topic is SOLVED.

Discussion stats
• 14 replies
• 905 views
• 2 likes
• 4 in conversation