How Plots are Overlaid

The following sections explain in more detail how the overlay process works and why some overlay constructs might not generate the graph you expect.

Statements Allowed in the Overlay Container

If you were to randomly place GTL statements within a LAYOUT OVERLAY block, you would often get compile errors. The following basic rules indicate which statements can be used within the layout block:
  • all 2D plot statements except SCATTERPLOTMATRIX
  • statements such as ENTRY, DISCRETELEGEND, and CONTINUOUSLEGEND
  • GRIDDED, LATTICE, and overlay-type layout blocks can be nested.
However, the following restrictions apply:
  • 3D plot statements cannot be included. Place these statements in a LAYOUT OVERLAY3D block.
  • ENTRYTITLE or ENTRYFOOTNOTE statements cannot be included. Place these statements outside the outermost layout block.
  • Other layout types such as PROTOTYPE, DATALATTICE, and DATAPANEL layouts cannot be nested in an OVERLAY layout.

Restrictions on Allowed Statements

Even among the statements that are valid within an OVERLAY layout, some restrictions apply to their use. For example, some dependent statements must be accompanied by at least one stand-alone plot statement, such as SCATTERPLOT or SERIESPLOT, in order to produce a usable graph. See Overview of Basic Statements and Options for lists of stand-alone and dependent statements.
For example, if you were to execute a template with the following layout block, it would produce an empty graph at runtime.
proc template;
  define statgraph test;
    begingraph;
      layout overlay;
        referenceline x=10;
      endlayout;
    endgraph;
  end;
run;
proc sgrender data=sashelp.class template=test;
run;
WARNING: A blank graph is produced. For possible causes, see the graphics
         template language documentation.
The GTL Reference documentation for the REFERENCELINE statement states an important requirement that explains why this graph is empty:
A REFERENCELINE statement can be used only within 2D overlay-type layouts (OVERLAY, OVERLAYEQUATED, or PROTOTYPE). A stand-alone plot statement that provides a sufficient data range for determining axis extents must be included in the layout. For example, a REFERENCELINE statement can be used with a scatter plot or a histogram statement.

Restrictions on Statement Combinations

Certain combinations of contained statements produce unexpected results. This section examines why these combinations do not produce the expected graph.
Consider the following template code, which generates a warning in the log:
proc template;
  define statgraph test;
    begingraph;
      layout overlay;
        boxplot x=age y=weight;
        regressionplot x=age y=weight;
      endlayout;
    endgraph;
  end;
run;
  
proc sgrender data=sashelp.class template=test;
run;
WARNING: REGRESSIONPLOT statement cannot be placed under a layout OVERLAY with a
         discrete axis. The plot will not be drawn.
When multiple statements that potentially contribute to axis construction are placed in the layout, the layout must verify that all data that is mapped to a particular axis is of the same type (all numeric, or all character, or all time). In addition, the layout must verify that each plot can use the requested axis type(s). In this case, the first statement in the layout is a BOXPLOT. Statements such as BOXPLOT, BOXPLOTPARM, BARCHART, and BARCHARTPARM treat the X=column as a categorical variable (regardless of data type) and build a DISCRETE (categorical) axis. Therefore, because BOXPLOT is the first statement in this example layout, it determines that the X axis is set to DISCRETE, and subsequent plots must be compatible with a discrete axis.
Many computed plots, such as REGRESSIONPLOT, LOESSPLOT, and ELLIPSE, require both X and Y axes to be of LINEAR type, which is a standard numeric interval axis type. Had you specified a SCATTERPLOT instead of a REGRESSIONPLOT, there would be no problem because a SCATTERPLOT can be displayed on either a DISCRETE or LINEAR X and Y axis. The end result of this example is a graph containing only the box plot output.
In this next example, the REGRESSIONPLOT and BOXPLOT statements have been switched:
layout overlay;
  regressionplot x=age y=weight;
  boxplot x=age y=weight;
endlayout;
WARNING: BOXPLOT statement has a conflict with the axis type. The plot will not be drawn.
In this case, the REGRESSIONPLOT (first plot) has fixed the type of the X axis to be LINEAR. Now the BOXPLOT is blocked because it needs a DISCRETE X axis. The end result of this example is a graph containing only the regression line.
Because a SCATTERPLOT can be included on either LINEAR or DISCRETE axes, you might think the following combination is valid:
layout overlay;
  scatterplot x=age y=weight;
  boxplot x=age y=weight;
endlayout;
WARNING: BOXPLOT statement has a conflict with the axis type. The plot will not be drawn.
In this case, the SCATTERPLOT (first statement) sets the X or Y axis type to LINEAR if the variable for that axis is numeric—even though the data might be categorical in nature. However, if the variable is character, the SCATTERPLOT must use a DISCRETE axis. So, once again the BOXPLOT is not displayed. If you switch the statements, both plots are drawn because after the X axis is fixed to be DISCRETE, the SCATTERPLOT can display numeric values on a DISCRETE axis.
When a character variable is used, the axis-type conflict often does not arise. The following combination works regardless of statement order. In either case, the DISCRETE X axis will display a combination of AGE values with box plots above and SEX values with scatter points above.
layout overlay;
  scatterplot x=sex y=weight;
  boxplot x=age y=weight;
endlayout;

Avoiding Plot Conflicts

In GTL, it is important to know what types of axes a given plot requires or can support. If you understand the basic ideas behind previous examples, you can use the following additional GTL syntax to avoid some of the problems caused by the first plot statement deciding the axis type:
  • use the PRIMARY=TRUE option on a plot statement to ensure that plot is used to determine the axis type
  • declare an axis type on the layout block.
Most non-dependent plot statements support the PRIMARY= option. By default, PRIMARY=TRUE for the first plot and PRIMARY=FALSE for the rest of the plots in the layout. On a per-axis basis, only one plot in an overlay can use PRIMARY=TRUE. If multiple plots specify PRIMARY=TRUE for the same axis, the last one encountered is considered primary. The plot that is designated as primary by default defines the axis types for the axes it uses, regardless of its order within the layout block. This is useful when you want a certain stacking order for the plots, but don't want the first plot to set the axis features, such as axis type and default axis label.
In the following example, the BOXPLOT sets the X axis to be DISCRETE and the Y axis to be LINEAR:
layout overlay;
  scatterplot x=age y=weight;
  boxplot x=age y=weight / primary=true ;
endlayout;
All layouts that manage axes provide options that enable you to control the axis features. The following example shows how to declare an axis type for the X axis. Any plot in the layout that cannot support a discrete axis will be dropped. Also note that specifying an axis type overrides the default axis type that is derived from the primary plot. Axis options are discussed in detail in Managing Axes in an OVERLAY Layout.
layout overlay / xaxisopts=(type=discrete) ;
  scatterplot x=age y=weight;
  boxplot x=age y=weight;
endlayout;
Some plot combinations can never be used. A histogram and bar chart look similar, but they have different data and axis requirements. The histogram must use a linear X axis and the bar chart must use a discrete X axis. The two plot types can never be overlaid.
layout overlay;
  barchart x=age;
  histogram age;
endlayout;
WARNING: HISTOGRAM statement has a conflict with the axis type. The plot will not be drawn.

layout overlay;
  histogram age;
  barchart x=age;
endlayout;
WARNING: BARCHART statement has a conflict with the axis type. The plot will not be drawn.

Plots with Incompatible Data

All plot statements have required argument(s) that map input data column(s) to one or more axes. Many plot statements have restrictions on the variable type (numeric or character) that can be used for the required arguments.
For example, the HISTOGRAM statement accepts only a numeric variable for the required argument. Consider the following template:
proc template;
  define statgraph test;
    begingraph;
      layout overlay;
        histogram sex;
      endlayout;
    endgraph;
  end;
run;
NOTE: STATGRAPH 'Test' has been saved to: SASUSER.TEMPLAT
If you were to create this template, you would not see a compilation error or warning because no variables are checked at compile time. However, you would see warnings in the log when the template is executed:
proc sgrender data=sashelp.class template=test;
run;
WARNING: Invalid data passed to BIN. Variable must be numeric.
WARNING: The histogram statement will not be drawn because one or more of the
         required arguments were not supplied.
WARNING: A blank graph is produced. For possible causes, see the graphics
         template language documentation.
In general, GTL produces a graph whenever possible. Plots in the overlay that can be drawn will be drawn. Plots are not drawn if they have incompatible data for the required arguments or if they cannot support the existing axis type(s). Hence, you might get a graph with some or none of the requested plot overlays.
The same strategy extends to plot options that have incompatible data. In the following example, the wrong variable name was used for the GROUP= option. In the data, the column is named SEX, not GENDER. This is not regarded as an error condition—the bar chart will be drawn without groups.
layout overlay;
  barchart x=age / group=gender;
endlayout;