Two Plots on One Page - RhoInc/sas-sgplot GitHub Wiki

Contents

  1. The Goal
  2. Setup
  3. RhoTables Version
  4. GREPLAY Version
  5. GTL Version

The Goal

On this page we learn how to arrange two independent plots side-by-side on one page.

the goal

Note that each individual plot is 4in x 4in and the overall plot is 8in x 4in.

Setup

We begin by defining some macro variables and creating a dataset, just to keep things simple below.

%let pgmdir = H:\D2G\OutputCapture\OneByTwo;
%let tbl = FIG_TAB;

proc sort data=sashelp.cars out=cars;
   by cylinders;
   where n(cylinders);
run;

RhoTables Version

The first step in the RhoTables version is to create two separate RTF files, one with a linear scale y-axis and the other with a log scale y-axis. Each of these individual plots will be created 4in x 4in.

options 
   nodate 
   nonumber
   orientation=landscape
   ;
ods graphics /
   outputfmt=png
   height=4in
   width=4in
   noborder
   ;

ods results off;
ods listing close;

*---------- begin left plot ----------;
ods rtf file="&pgmdir\rt4_&tbl._left.rtf";

proc sgplot data=cars;
   scatter y=enginesize x=horsepower;
run;

ods rtf close;
*---------- end left plot ----------;

*---------- begin right plot ----------;
ods rtf file="&pgmdir\rt4_&tbl._right.rtf";

proc sgplot data=cars;
   scatter y=enginesize x=horsepower;
   yaxis type=log;
run;

ods rtf close;
*---------- end right plot ----------;

ods listing;
ods results on;

Linear Scale rt4 left

Log Scale rt4 right

We now use RhoTables and with two column definitions: Def1 for the left/linear plot and Def2 for the right/log plot.

*---------- create a one-record dataset ----------;
data dummy;
   x = " ";
run;

*---------- put plots in columns 1 and 2 using rt4pic ----------;
%let Def1 = COL|1|C|%rt4pic(&pgmdir\rt4_&tbl._left.rtf)|wid(62);
%let Def2 = COL|2|C|%rt4pic(&pgmdir\rt4_&tbl._right.rtf)|wid(62);

*---------- RhoTables call ----------;
%RhoTables4
   (ItemName=&tbl
   ,ItemType=figure
   ,Style=Table
   ,LineSize=126
   ,PageSize=52
   ,Data=dummy
   );```

![rt4 combined](https://github.com/RhoInc/sas-sgplot/raw/master/img/one_by_two/the_goal.png)

Pretty straightforward, eh!?

RhoTables4 also provides you with the ability to use the `LVL()` option to put multiple graphs on multiple rows. Assuming you are connected to the Rho network, the RhoTables4 documentation can be found [here](http://sharepoint.vpn.rhoworld.com/kb/Pages/RhoTables4_User_Guide.docx). The relevant content is towards the end of section 13.1.2.

<a name="GREPLAY-Version"/>

## GREPLAY Version

A more generic (i.e., non-RhoTables4-dependent) method for arranging multiple plots on a page is to use GREPLAY. An outline of the GREPLAY process is:

1. Create separate PNGs for each individual plot.
1. Create separate GSLIDEs for each individual plot.
1. Use GREPLAY to combine the GSLIDEs into a single graphic.

This outline makes it sound like it's not so bad. Do not be mislead. There is a lot of black magic and fiddly bits throughout the process, most of which is not included below. If you want to see all of the gory details, you can find them [here](https://github.com/RhoInc/sas-sgplot/blob/master/src/onebytwo_greplay.sas).

The first step in the GREPLAY method is to create separate PNGs for each individual plot.

*---------- left plot ----------; ods graphics / imagename="greplay_&tbl._left";

proc sgplot data=cars; scatter y=enginesize x=horsepower; run;

*---------- right plot ----------; ods graphics / imagename="greplay_&tbl._right";

proc sgplot data=cars; scatter y=enginesize x=horsepower; yaxis type=log; run;


Linear Scale <br>
![greplay left](https://github.com/RhoInc/sas-sgplot/raw/master/img/one_by_two/greplay_left.png)

Log Scale <br>
![greplay right](https://github.com/RhoInc/sas-sgplot/raw/master/img/one_by_two/greplay_right.png)

Next we create GSLIDE output for each individual plot. Note that this output is not saved in a PNG or RTF or any other external file type. The GSLIDE output is created as a catalog entry within SAS. There are ways to get at it and look at it, but we don't really care about that. It is enough for us to simply create the GSLIDE output in the catalog and know that it's there. Embrace the mystery!

goptions iback="&pgmdir/greplay_&tbl._left.png" imagestyle=fit; proc gslide; run;quit;

goptions iback="&pgmdir/greplay_&tbl._right.png" imagestyle=fit; proc gslide; run;quit;


As our penultimate step, we will create a template called `onebytwo`. The point of this template is to "receive" the two GSLIDE outputs that we created above. The syntax is so darned confusing (e.g., ULX = X coordinate of the Upper Left corner) that I'm not even going to show it to you. 

Having created the template, we now "replay" the two GSLIDE outputs into the two rectangles created by the template.

<more fiddly bits>

ods results off;
ods listing close;
ods rtf file="&pgmdir/greplay_&tbl._pre.rtf";

proc greplay <hidden options>;
   treplay 
      1:gslide 
      2:gslide1
      ;
run;quit;

ods rtf close;
ods listing;
ods results on;

greplay combined

This GREPLAY step leaves us with a plain ole RTF file. We will leave the final RhoTables step as an exercise for the reader.

GTL Version

One very nice thing about SGPLOT is the TMPLOUT option. This option converts your SGPLOT code into GTL code.

ods results off;
ods listing close;

ods rtf file="&pgmdir\gtl_&tbl._left.rtf";

proc sgplot data=cars tmplout="&pgmdir\gtl_&tbl._left.sas";
   scatter y=enginesize x=horsepower;
run;

ods rtf close;

ods rtf file="&pgmdir\gtl_&tbl._right.rtf";

proc sgplot data=cars tmplout="&pgmdir\gtl_&tbl._right.sas";
   scatter y=enginesize x=horsepower;
   yaxis type=log;
run;

ods rtf close;

ods listing;
ods results on;

This code creates two SAS files: gtl_FIG_TAB_left.sas and gtl_FIG_TAB_right.sas. Looking at the contents of the left file, we see the following:

proc template;
define statgraph sgplot;
begingraph /;
layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split);
   ScatterPlot X=Horsepower Y=EngineSize / primary=true LegendLabel="Engine Size (L)" NAME="SCATTER";
endlayout;
endgraph;
end;
run;

The first 3 lines and last 3 lines are not of interest. The middle 3 lines are what provide the details of how to produce the plot.

In GTL you can use the LAYOUT GRIDDED statement along with the COLUMNS=2 option in order to specify two plots should be side-by-side.

proc template;
   define statgraph onebytwo;
      begingraph;

         layout gridded / columns=2;

            *--- insert code for first plot here ---;

            *--- insert code for second plot here ---;

         endlayout;

      endgraph;
   end;
run;

Now we just pull the middle 3 lines out of both the left and right programs and insert them into the above shell.

proc template;
   define statgraph onebytwo;
      begingraph;

         layout gridded / columns=2;

            *--- code for left plot ---;
            layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split);
               ScatterPlot X=Horsepower Y=EngineSize / primary=true LegendLabel="Engine Size (L)" NAME="SCATTER";
            endlayout;

            *--- code for right plot ---;
            layout overlay / y2axisopts=(labelFitPolicy=Split) yaxisopts=( labelFitPolicy=Split type=log ) y2axisopts=(labelFitPolicy=Split);
               ScatterPlot X=Horsepower Y=EngineSize / primary=true LegendLabel="Engine Size (L)" NAME="SCATTER";
            endlayout;

         endlayout;

      endgraph;
   end;
run;

To finish things off we use SGRENDER to pair the GTL code with the dataset, thus producing the graphic.

options 
   nodate 
   nonumber
   orientation=landscape
   ;
ods graphics /
   outputfmt=png
   height=4in
   width=8in
   noborder
   ;

ods results off;
ods listing close;
ods rtf file="&pgmdir\gtl_&tbl..rtf";

proc sgrender template=onebytwo data=cars;
run;

ods rtf close;
ods listing;
ods results on;

gtl combined

This SGRENDER step leaves us with a plain ole RTF file. We will leave the final RhoTables step as an exercise for the reader.