*! Help file version 2.26 (4Nov2023) written by Mead Over (mover@cgdev.org)

*! This help file is based on the help file for grc1leg by Vince Wiggins. See -Authors-.

help for grc1leg2version 2.26 4Nov2023

Title

grc1leg2 -- Combine multiple graphs with a single common legend

Syntax

grc1leg2
name
[name ...]
[,
combine_options
legend_options
title_options
gr_display_options
]

where name is

name description

simplename name of graph in memory*
name.gph name of graph stored on disk*
"name" name of graph stored on disk*

The "wildcard" characters "*" and "?" are not permitted in the list of graph names to be combined.

and where combine_options are:

combine_options description

colfirst display down columns

rows:(#) | cols:(#) display in
# rows or # columns

holes:(numlist) positions to leave blank

iscale([*]#) size of text and markers

altshrink alternate scaling of text, etc.

imargin(marginstyle) margins for individual
graphs

ycommon give y axes common scales

xcommon give x axes common scales

title_options titles to appear on combined graph

region_options outlining, shading, aspect ratio

commonscheme put graphs on common scheme

scheme(schemename) overall look

nodraw suppress display of combined graph

name(name, ...) specify name for
combined graph

saving(filename, ...) save combined
graph in file. (If using option lrows(integer) or lcols(integer), specify the sub-option "asis".)

and the legend_options are

legend_options description

Specifying from which component graph to borrow the legend

legendfrom(name) specifies the graph from which the legend
for the combined graphs is to be taken.
The argument name must match one of the names from the list of graph names specified.
(Default is the first graph listed.)*

hidelegendfrom Hide the graph from which legend is taken

Changing the position of the legend

position(clockpos) Where legend appears in the combined graph*

ring(ringpos) where legend appears (within or outside the plot region)*

lxoffset(real) Shift the legend's horizontal position to the right or left

lyoffset(real) Shift the legend's vertical position up or down

span "Center" the legend*

loff Suppress the combined legend

Arranging the elements of the legend

lholes(numlist) specifies which positions in the legend array are to be left empty

lcols(integer) Reset the number of columns in the legend+

lrows(integer) Reset the number of rows in the legend+

Specifying the legend's title and/or subititle

ltitle(string) Legend title

lsubtitle(string) Legend subtitle

Changing the size of the legend and its elements

legscale(size) Override grc1leg2's default size reduction of all the following legend elements.

ltsize(textsizestyle) Size of the text in the legend title (overrides default resizing or user-specified legscale())

lsubtsize(size) Size of the text in the legend subtitle (overrides default resizing or user-specified legscale())

lmsize(markersizestyle) Size of the marker keys in the legend (overrides default resizing or user-specified legscale())

symxsize(size) Set the width of the symbol keys in the legend (overrides default resizing or user-specified legscale())

symysize(size) Set the height of the symbol keys in the legend (overrides default resizing or user-specified legscale())

labsize(textsizestyle) Size of the text of the key labels in the legend (overrides default resizing or user-specified legscale())

noautosize Disable grc1leg2's default automatic resizing (typically shrinking) of legend elements.

Stata's many other legend options
are not available here in grc1leg2.
To use these other legend options,
apply them to the legend to be used in the combined graph.
See Examples 3.10a, b an c, Example 3.12 and Example 3.13
for guidance on using legend options not available in grc1leg2.

and the title_options are:

title_options description

x-title
xtob1title Suppress the xtitle on individual panels
and use the xtitle from one of the panels
as the b1title on the combined graph.

xtitlefrom:(name) Graph from which
to take the xtitle. Default is from the first graph.

xtsize(textsizestyle) Modify the size of the borrowed
x-title as displayed on the combined graph.

y-title on the left y-axis
ytol1title or l1tol1title Suppress the ytitle or l1title on the left y-axis of the individual panels
and use the ytitle or l1title from one of the panels
as the l1title on the left y-axis of the combined graph.

titlefrom(name) Graph from which to take the ytitle or l1title from the left y-axis.
Default is from the first graph.

ytsize(textsizestyle) Modify the size of the borrowed
y-title as displayed on the left y-axis of the combined graph.

y-title on the right y-axis
y2tor1title or r1tor1title Suppress the ytitle or r1title on the right side of individual panels
and use the ytitle or r1title from the right y-axis of one of the panels
as the r1title on the combined graph.

titlefrom(name) Graph from which to take the ytitle or r1title from the right y-axis.
Default is from the first graph.

y2tsize(textsizestyle) Modify the size of the borrowed
y-title as displayed on the right y-axis of the combined graph.

main title
maintotoptitle Suppress the main title on individual panels
and use the main title from one of the panels
as the overall title on the combined graph.

mainfrom:(name) Graph from which to take
the main title. Default is from the first graph.
For backward compatibility, maintitlefrom:(name)
can be used instead of option mainfrom:(name).

mtsize(textsizestyle) Modify the size of the borrowed
main title as displayed on the combined graph.

subtitle
subtosubtitle Suppress the subtitle on individual panels
and use the subtitle from one of the panels
as the overall subtitle on the combined graph.

subfrom:(name) Graph from which to take
the subtitle. Default is from the first graph.

stsize(textsizestyle) Modify the size of the borrowed
subtitle as displayed on the combined graph.

note
notetonote Suppress the note on individual panels
and use the note from one of the panels
as the overall note on the combined graph.

notefrom:(name) Graph from which to take
the note. Default is from the first graph.

ntsize(textsizestyle) Modify the size of the borrowed
note as displayed on the combined graph.

and the gr_display_options and miscellaneous options are:

gr_display_options description

ysize:(#) change height of combined graph (in inches)

xsize:(#) change width of combined graph (in inches)

margins:(marginstyle) change outer margins
of combined graph

scale(#) resize text, markers, and
line widths of combined graph

scheme(schemename) change overall look
of combined graph and legend

commonscheme put graphs on common scheme

dots Display dots to show grc1leg2's progress

graphon Leave the graphics setting as set by the user.

Options dots and graphon do not appear in the
dialog.

Description

grc1leg2 is an enhanced version of Vince Wiggins' grc1leg.
Like grc1leg, grc1leg2 is a wrapper for Stata's graph combine,
invoking its ability to array separate, previously drawn graphs as panels
in a single combined graph.
In addition to allowing all the graph combine options, grc1leg2:

(a) suppresses the display of the legends on the component graphs;*

(b) creates a legend for the combined graph by borrowing the legend
previously defined for one of the component graphs;*

(c) optionally changes the position of the legend on the combined graph;*

(d) optionally suppresses the x-titles or the y-titles of the component graphs,
borrowing them for the combined graph;

(e) optionally suppresses the main titles, subtitles or notes of the component graphs,
borrowing one of them for the corresponding text element of the combined graph;

(f) by default, shrinks all elements of the legend on the combined graph so that
the sizes of markers and symbols in the legend approximately match their sizes
in the component panels;

(g) allows user to override the default size of some or all the elements
of the legend;

(h) facilitates the calibration and coding of fine adjustments
using the dialog grc1leg2;

(i) optionally removes all legends from the combined graph (with the option loff);

(j) accepts component graphs constructed by -graph, by()-, -graph combine- or grc1leg2;

(k) optionally creates a legend for the combined graph that merges the legends of
component panels (Example 3.10);

(l) enables application of the graph display options to the created combined graph.

(m) can create an Excel-style "bar-of-pie- graph (see Example 3.10c).

By default, the characteristics of the common legend are inherited from the original
version of the legend in the first component graph, or in the graph specified by the option legendfrom(name).
With grc1leg2's legend options,
the user can precisely control the placement of the common legend within the combined graph.
Other legend options allow the user to override
some of the characteristics of the legend inherited from its original creation
as part of one of the component graphs. For example, the size of all markers,
symbols or labels in the legend can be increased or decreased.

When an analyst assembles multiple component graphs into a single combined graph,
the separate component graphs often share a common x-axis, y-axis or both.
In these situations, the appearance and logic of the graph is improved by
stripping the titles of the shared axis from all the component graphs,
replacing them with a single title for all the shared axes. grc1leg2's
title options serve this purpose, allowing
the user to replace the separate xtitles or ytitles
on each of the individual graphs with a single b1title, l1title or r1title
on the combined graph, which is "borrowed" from one of the component graphs.
See examples 3.3 and 3.9.

Since multi-panel graphs (i.e. combined graphs) are inherently more difficult
for a reader to interpret than a single graph, it is wise to simplify multi-panel graphs
as much as possible. One way to simplify is to assure that the same legend
applies to all component graphs. When all panels use the same markers, symbols and
labels, the legend from any of the component graphs can serve as the legend
for all of them. grc1leg2, like its predecessor grc1leg,
simply suppresses the legends on all the component graphs and repurposes
or "borrows" one of those legends to serve as the legend for the combined graph.

But there may be situations in which a user wishes
to assemble a combined or multi-panel graph from component graphs which
contain different variables, markers, or fill patterns.
In this situation, none of the component graphs
has a legend that works for all panels of the combined graph.
Using the option legendfrom(name) together with the option hidelegendfrom
enables the user to create a single legend which includes legend
"keys" from all the combined graphs.
See example 3.10.

Legend options

Specifying from which component graph to borrow the legend

legendfrom(name) specifies the graph from which the legend for
the combined graphs is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified. The single legend displayed by
grc1leg2 is drawn from either the first graph name
appearing after the the grc1leg2 command or from the graph named
by the legendfrom(name) option. By default, all
the characteristics of the legend displayed by grc1leg2 are inherited
from the legend in that component graph.*

hidelegendfrom hides the graph from which the legend is taken.
This option is only useful when none of the component graphs
contains all the "keys"
for the combined graph.
The graph to be hidden should appear last in the list of named graphs.
See example 3.10
.

Changing the position of the legend

position(clockpos) and ring(ringpos)
override the default location of the legend, which is usually centered
below the plot region. position() specifies a direction (sic)
according to the hours on the dial of a 12-hour clock, and ring()
specifies the distance from the plot region.*

ring(0) specifies that the legend be placed inside the plot,
rather than on its periphery. ring(k) for k>0,
specifies positions outside the plot region; the larger the ring()
value, the farther away from the plot region is the legend. ring()
values may be integers or nonintegers and are treated ordinally. The default is 1.
See Where legends appear for more detail.*

position(12) puts the legend directly above the plot region
(assuming ring()>0), position(3) directly to the right
of the plot region, and so on.*

See the
examples
below for guidance on using the
ring(ringpos)
and the
position:(clockpos)
options and see
Positioning of titles in
title_options for more information on
the position() and ring() suboptions.

span specifies that the legend is to be placed in an area spanning the
entire width (or height) of the graph rather than an area spanning the
plot region.
This affects whether the legend is centered with respect to the plot
region or the entire graph.
See Spanning in
title_options for more information on span.*

loff This option "hides" the combined legend. With this option,
grc1leg2 has the effect of removing from the combined graph
all the legends on the component graphs.
Since this option only hides the combined legend, but does not delete it,
the user can reveal the legend by opening the graph in the
graph editor, selecting the legend and clicking "Show".

Arranging the elements of the legend

lxoffset(real) and lyoffset(real)	enable fine
adjustments to the position of the legend on the combined graph.
The user should first roughly determine the legend's position
with the options ring(ringpos) and position(clockpos)
and then make finer adjustments as necessary with the options
lxoffset(real) and lyoffset(real).

lholes(numlist) inserts one or more gaps or "holes" in designated
locations in the legend as described here.
Potentially useful for separating legend keys into groups.

lcols(integer) and lrows(integer)
specify how the legend symbols and keys are arrayed. These options invoke the
Stata legend options cols() and rows()
as described here. However,
unlike the changes made by other grc1leg2 legend-modifying options,
the changes to the legend layout effected by
lcols(integer) and lrows(integer) are not retained
in a "live" .gph file. To save the rearranged
legend layout to a .gph file, specify the sub-option asis
in grc1leg2's saving option
or on the graph save command.
Alternatively, avoid using lcols(integer) and lrows(integer)
by rearranging the legend layout in the component graph
before executing grc1leg2.

Specifying the legend's title and/or subititle

ltitle(text) and lsubtitle(text)
invoke the legend options title(text) and subtitle(text)
documented in help title options, but do not permit
the suboptions documented there. To control the size of the text of the
legend's title and subtitle, see the options
ltsize:(textsizestyle) and lsubtsize(textsizestyle).
Specifying zero suppresses this title on the combined graph.

Changing the size of the legend and its elements

legscale(size) overrides grc1leg2's default size reduction
of all legend elements. Just as Stata's gr combine
reduces the the size of text and markers in the graphs it combines,
grc1leg2 automatically reduces the size of all elements in the combined legend
as the number of component graphs increases. For example, if there are
two component graphs, grc1leg2 internally sets legscale(size) to "*0.8",
which reduces the size of all elements in the borrowed legend by 20%.
If there are eight or nine component graphs, grc1leg2 sets
legscale(size) to "*0.6". This default behavior has the effect
of shrinking the size of markers in the legend to approximately
match the size of those markers in the component graphs.

By specifying legscale(size), the user can shrink or expand all elements of the legend.
For example, by specifying legscale(*1.1), the user instructs grc1leg2
to magnify the size of all legend elements by 10%.
legscale(*0.8) shrinks all elements by 20%.

To alter the size of one type of legend element, the user specifies
the size multiplier for that element type. Options
ltsize(textsizestyle) and lsubtsize(textsizestyle)
modify the size of the title or subtitle of the borrowed legend,
whether they were in the original legend or added by grc1leg2's
options ltitle(text) and lsubtitle(text).
Specifying these options overrides legscale(size) for that element type.

Four options are available to alter the size of the legend's markers,
symbols and labels:	lmsize(markersizestyle),
symxsize(size), symysize(size)
and labsize(textsizestyle).
Specifying these options overrides legscale(size) for that element type.

Stata's twoway graph commands use graph "markers"
each of which is associated with a set of points in the graph.
The option lmsize(markersizestyle) enables grc1leg2
to control the size of these markers within the legend
independently of their size(s) in the component graphs. However, some graphs,
notably those produced by graph pie and graph bar,
contain no markers. Their legends contain symbols, but no markers.
When combining these graphs, grc1leg2
permits the option lmsize(markersizestyle), but it has no effect.
For legends with markers but no symbols, the options symxsize(size) and
symysize(size) are permitted but have no effect.

By default, grc1leg2 reduces the size of all legend elements to correspond
to their displayed sizes in the combined graph.
Thus the legend and all its elements get smaller with additional component graphs.
Option noautosize disables grc1leg2's default automatic downsizing
of legend elements.

Title options

xtob1title
suppresses the xtitle on individual panels
and uses the xtitle from one of the panels
as the b1title on the bottom margin of the combined graph. This option
is consistent with this program's objective of simplifying
and de-cluttering a multi-panel combined graph.
However it should never be used if the panels have
different x axes. Thus, it is not a default option.

xtitlefrom:(name)
specifies the graph from which the xtitle for
the combined graphs is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified.

xtsize(textsizestyle)
specifies the size of the borrowed x-title as displayed on the combined graph.
Specifying zero suppresses this title on the combined graph.

ytol1title
suppresses the ytitle on the left y-axis of individual panels
and uses the ytitle from one of the panels
as the l1title on the left margin of the combined graph. This option
is consistent with this program's objective of simplifying
and de-cluttering a multi-panel combined graph.
However it should only be used if the left y-axes of the separate graphs
being combined can be described by the same y-axis title.
Thus, it is not a default option.

ytitlefrom:(name)
specifies the graph from which the ytitle for
the combined graphs is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified.

l1tol1title
suppresses the l1title on the left y-axis of individual panels
and uses the l1title from one of the panels
as the l1title on the left margin of the combined graph.

l1titlefrom(name)
specifies the graph from which the l1title for
the combined graphs is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified.

ytsize(textsizestyle)
specifies the size of the borrowed y-title as displayed on the left y-axis of the combined graph.
Specifying zero suppresses this title on the combined graph.

y2tor1title
suppresses the ytitle on the right y-axis of individual panels
and uses the ytitle from the right y-axis of one of the panels
as the r1title on the right margin of the combined graph.

y2titlefrom(name)
specifies the graph from which the ytitle for the right y-axis of
the combined graph is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified.

r1tor1title
suppresses the r1title on the right y-axis of individual panels
and uses the r1title from the right y-axis of one of the panels
as the r1title on the right margin of the combined graph.

r1titlefrom(name)
specifies the graph from which the r1title for the right y-axis of
the combined graph is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified.

y2tsize(textsizestyle)
specifies the size of the borrowed y-title as displayed on the right y-axis of the combined graph.
Specifying zero suppresses this title on the combined graph.

maintotoptitle
suppresses the main title on individual panels
and uses the main title from one of the panels
as the overall title on the combined graph.

maintitlefrom:(name)
specifies the graph from which the overall title for
the combined graphs is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified.

mtsize(textsizestyle)
specifies the size of the borrowed main title as displayed on the combined graph.
Specifying zero suppresses this title on the combined graph.

subtosubtitle
suppresses the subtitle on individual panels
and uses the subtitle from one of the panels
as the overall subtitle on the combined graph.

subfrom:(name)
specifies the graph from which the overall subtitle for
the combined graphs is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified.

stsize(textsizestyle)
specifies the size of the borrowed main title as displayed on the combined graph.
Specifying zero suppresses this title on the combined graph.

notetonote
suppresses the note on individual panels
and uses the note from one of the panels
as the overall note on the combined graph.

notefrom:(name)
specifies the graph from which the overall note for
the combined graphs is to be taken. The default is the first graph in the
list. The argument name must match one of the names from the list of
graph names specified.

ntsize(textsizestyle)
specifies the size of the borrowed note as displayed on the combined graph.
Specifying zero suppresses this note on the combined graph.

Graph display and miscellaneous options

gr_display_options enable the user to control the aspect ratio of
the combined graph (by setting xsize(#) and ysize(#)) or
to adjust its overall margins or scale. The option
scheme(schemename) overrules
the graphics schemes originally used on the individual graphs
to impose a common scheme on all the component graphs and on the
combined graph. See help for graph display
for further details on these options.
See Example 3.11.

In order to save time and avoid some unneeded manipulation of the graphics window,
grc1leg2 sets graphics to set graphics off
while it is working and then returns to the user's graphics setting
in order to display the combined graph. This procedure has the
disadvantage of closing any open graphics windows. To suppress this
behavior and allow -grc1leg2- to keep existing graphics windows
open while constructing the combined graph, specify the
graphon option. When the graphon option is not specified
and a syntax error of some kind causes grc1leg2 to crash,
the user may have to issue a set graphics on command
(or exit and restart Stata) in order to display graphs.

Unless suppressed by the option nodots, grc1leg2 displays a sequence
of dots which advances at each stage of processing.

Graph combine options

combine_options are passed through to the graph combine command.
They specify how the component graphs are arrayed, titling of the combined
graphs, and other common graph options. Among the graph combine
options most useful here in grc21leg2 are the workhorse options
name(name, ...) and
saving(filename,...) and the
holes(numlist) option which can be used
to make space for placement of the combined legend. See
graph combine for details on all the graph combine options
and the examples in this help file for
their use with graph combine and grc1leg2.

Remarks

grc1leg2 is like Stata's graph combine except it
reduces the clutter in the combined graph.
The legend displayed is one of the legends from the graphs being combined.
Optionally grc1leg2 can also suppress the titles
on each of the individual graphs, borrowing one of them to apply to the combined graph.
grc1leg2 can also alter characteristics of the borrowed legend and titles
as they are displayed in the combined graph.
Otherwise, grc1leg2 behaves like graph_combine.

When constructing a multi-panel graph with at least three panels,
it is rarely satisfying for each panel to have its own legend.
In most cases, it would be analytically and aesthetically preferable
to have a single common legend, with a common set of legend keys,
for all panels in the graph.

Stata's graph commands offer several ways to display a single
common legend for all the panels in a multi-panel graph.
However, by default, Stata puts the legend of a multi-panel
graph outside the multi-panel layout, squeezing all the panels
either vertically or horizontally. This solution works logically,
but typically makes it harder to read the separate panels.

With appropriate options, you can enhance the legibility
of the multi-panel graph by leaving room for the legend
in the multi-panel layout and using the approriate
legend options to place the legend in that empty spot.
In Stata there are several ways to accomplish this objective without
resorting to the graph editor:

1.	One-step procedure, using graph ..., by()

a.	When feasible, construct the multi-panel graph using
a single graph command with the -by- option. Stata
will automatically construct a single legend with keys
that are common across all panels of the graph.
Nick Cox's tip #139
here
gives many examples showing the power
of using graph ..., by().

b.	Optimum legend placement is typically in a "hole"
at the bottom right of the multi-panel layout.
To achieve this effect, use the legend options:
- at(#) position(5) -.
The at(#) option is a powerful tool for placing a legend
within a "hole" in a multi-panel graph. The absence of such an
option for the graph combine command is a major
reason for the existence of this program, grc1leg2.

c.	Unlike the gr combine and the
grc1leg2 commands discussed below,
the graph ..., by() command accepts the full
range of legend options. See this
help file for details.

2.	Two-step procedure, using gr combine

a.	Construct and name or rename the graphs for each of the separate panels

i. Assure that the assignment of marker styles, line styles
and, especially, colors are consistent with the legend of the last of the named graphs.

ii. Suppress the legend in all but the last of the separate graphs.

iii. For the last graph, specify legend options
-ring(0) pos(5) xoffset(#)-
with experimentation on the value of the offset.
This is also the place to specify any other
of the full range of Stata
legend options.

b.	Combine the named graphs using gr combine.

Since gr combine does not have a legend option,
use the layout options -cols(#)- and/or -rows(#)- to assure
that the last specifed graph will be in the
bottom row of the panel layout. This result is assured
if the number of component graphs is odd and no "holes"
are specified prior to the lower right position.
See this
discussion on the Statalist Forum.

3.	Two-step procedure using this program, grc1leg2

a.	Construct and name or rename the graphs for each of the separate panels

i. Assure that the assignment of marker styles, line styles
and, especially, colors are consistent with the legend of one of the named graphs.

ii. No need to suppress the legends on any of the
component graphs

iii. For one of the component graphs, by default the first,
specify any desired legend options
that are not allowed by the grc1leg2 command as
documented in this help file.

b.	Combine the named graphs using grc1leg2

i.	Unlike gr combine, grc1leg2 has
legend options to control legend placement.
For example, to achieve a similar legend placement to
method -2- above, one can specify
ring(0) and pos(5) as options on
the grc1leg2 command instead of on
the command to construct one of the component graphs.

ii. Optionally use the grc1leg2 options
lxoffset(real) and lxyoffset(real)
to refine the legend placement.

iii. Optionally use the grc1leg2 options legsize(size)
to shrink or enlarge the entire legend. The user may also choose
to shrink or enlarge all the legend elements of a type
by experimenting with the options lmsize(size),
labsize(textsizestyle), symysize(size) and symxsize(size).
These options override the key marker, label and symbol sizes
specified in step 3.a.iii above.

iv. Optionally use the xtob1title(text) option to suppress the
xtitle on each of the individual graphs and insert an overall
b1title for the combined multi-panel graph. Of course,
this option is only approriate if all panels should have the same
xtitle

v. Optionally use the ytol1title(text) option to suppress the
ytitle on each of the individual graphs and insert an overall
l1title for the combined multi-panel graph.
Analagously with option xtob1title(text),
this option is only approriate if all panels should have the same
ytitle

vi. Optionally use the y2tor1title(text) option to suppress the
ytitle on the second y-axis (on the right margin)
of each of the individual graphs and insert an overall
r1title for the combined multi-panel graph.
As for option ytol1title(text),
this option is only approriate if all panels should have the same
ytitle on the right y-axis

The above strategies for placing a legend in a "hole" in the multi-panel
combined graph apply when the multi-panel graph has at least 3 component graphs
or panels.
The strategies for placing a common legend are more restricted when there are only
two panels, because in that case
Stata's graph ..., by()
and gr combine commands do not respond to the
holes(numlist) option.
When there are only two panels, grc1leg2 is useful for controlling the
placement of the legend on the combined graph and for reducing graph clutter
by suppressing the x- and y-titles on the component graphs,
moving them to the b1- and l1- titles of the combined graph.
The do file entitled grc1test.do, available with this
//digital.cgdev.org/doc/stata/MO/Misc")"':package
as an "ancillary file, includes applications of grc1leg2 when there are only two panels.

Examples

The following examples demonstrate all three above approaches
to appending a single legend to a graph combining three or more panels.

To skip the examples using gr ..., by() or gr combine,
going directly to the examples using grc1leg2:

o First set up the data by clicking
here

o Then generate the four component graphs by clicking
here.

o Then scroll down to the grc1leg2 Examples 3.0 ff. here.

To try all examples, start here:

sysuse auto2

gen byte qual = 1*(rep78<3)+2*(rep78==3)+3*(rep78>=4)

lab def qual 1 "Low Quality" 2 "Medium Quality" 3 "High Quality"

lab value qual qual

lab var qual "Quality - Mapping of rep78 into trichotomy"

tab rep78 qual, mi

*	(For simplicity, we assign missing values of rep78 to qual==3.)

(click to set up the data, prior to running the examples below)

1.	Examples of the one-step procedure, using graph ..., by()

===============================================================

Example 1.0: Using a single graph command with the -by- option
automatically assigns a single legend to a combined graph.
Here are examples with three panels and with five panels.
Example 1.0 shows the result of graph ..., by()
without options to control the placement of the legend.

Example 1.0: A three-panel graph using graph ..., by() with default legend placement

twoway ///
(scatter mpg weight) ///
(lfit mpg weight ), ///
by(qual, ///
title("Ex. 1.0: Three panels, with legend at 6 o'clock") ///
subtitle("Use -twoway ..., by()- without options") ///
) ///
name(grby3dflt, replace)

(click to run, after clicking above to set up the data)

Example 1.1: For better control over legend placement, both the following examples use
the options at(#) and pos(#) to insert the legend
into the multi-panel array. Note that two legend
options are specified in each command. The legend option
within the by() definition controls the organization
and appearance of the legend; the one outside the by() definition
determines the placement of the legend. See
help by_options
for details.

Example 1.1: A three-panel graph using graph ..., by()

twoway ///
(scatter mpg weight) ///
(lfit mpg weight ), ///
legend(col(1)) ///
by(qual, ///
legend(pos(0) at(4)) ///
title("Three panels, with legend in a hole") ///
subtitle("Use -twoway ..., by()- with -at(4) pos(5)-") ///
) ///
name(grby3, replace)

(click to run Example 1.1)

Example 1.2: A five-panel graph using graph ..., by()

twoway ///
(scatter mpg weight) ///
(lfit mpg weight ), ///
legend(col(1)) ///
by(rep78, ///
legend(pos(0) at(6)) ///
title("Five panels, with legend in a hole") ///
subtitle("Use -twoway ..., by()- with -at(6) pos(0)-") ///
) ///
name(grby5, replace)

(click to run Example 1.2)

2.	Examples of a two-step procedure, using gr combine:

=======================================================

The Stata command gr combine does not have a legend option.
In order for the combined graph to have only one legend,
we must assure that only 1 of the component graphs has a legend.
Using gr combine, the two steps to the combined graph with legend are:

First step: Create the component graphs and name them panel1, 2, 3 and 0.
In order for gr combine to display a single common legend,
the legends must be suppressed on all but one of the individual component
graphs at the time they are originally created.
The legend to be displayed can be on the last of the component graphs
and can be moved to a "hole" using the xoffset and yoffset options
at the time this component graph is originally created.
Executing the following code creates the named memory graphs panel1,
panel2, panel3 and panel0 but displays no graphic output.

set graph off

twoway ///
(scatter mpg weight if qual==1) ///
(lfit mpg weight if qual==1), ///
ytitle(Miles per gallon) ///
subtitle("Low Quality") ///
legend(col(1) off) /// Hidden legend has one column
name(panel1, replace)

twoway ///
(scatter mpg weight if qual==2) ///
(lfit mpg weight if qual==2), ///
ytitle(Miles per gallon) ///
subtitle("Medium Quality") ///
legend(row(1) off) /// Hidden legend has one row
name(panel2, replace)

twoway ///
(scatter mpg weight if qual==3) ///
(lfit mpg weight if qual==3), ///
ytitle(Miles per gallon) ///
subtitle("High Quality") ///
legend(col(1) ring(0) pos(3) xoffset(55) ) ///
name(panel3, replace)

twoway ///
(scatter mpg weight) ///
(lfit mpg weight), ///
ytitle(Miles per gallon) ///
subtitle("Entire sample") ///
legend(col(1) ring(0) pos(3) xoffset(40) ) ///
name(panel0, replace)
set graph on

*	List the named graphs now in memory
graph dir, memory

(click to run the above code, before running Examples 2.x or Examples 3.x.

Example 2.1: Second step: By turning off the legends on
all but the last of several component graphs
and specifying the legend on the last graph
with options -ring(0) pos(5) xoffset(#)-,
gr combine does a passable job of
creating a multi-panel graph with a single legend.
For this approach to work, properly calibrate the offset
and arrange the placement of the panels to allow
for a "hole" which can accommodate the legend.

Example 2.1: Assemble three one-panel graphs using gr_combine

gr combine panel1 panel2 panel3, ///
xcommon ycommon ///
title("Three panels, with legend in a hole") ///
subtitle("Use -gr combine ... , having specified" ///
"-col(1) ring(0) pos(3) xoffset(55)- on -panel3-") ///
name(grcomb3, replace)

(click to run, after creating panels 0, 1, 2 & 3 above)

Example 2.2: A disadvantage of using gr combine as in Example 2.1
compared with using graph twoway ..., by()
or grc1leg2 as demonstrated in examples 1.x and 3.x
respectively is that gr combine uses superfluous ink
to repeat the axis titles for each panel.
(With extra work, the user could suppress the axis titles
on each of the component graphs before combining them using gr combine.)

gr combine can equally well display a single legend
when there are five panels. In Example 2.2 the legend from the
graph in the fifth panel is placed in the space that
would otherwise be occupied by a sixth panel.

Example 2.2: Using gr_combine with five panels

gr combine panel1 panel2 panel1 panel2 panel3, ///
xcommon ycommon ///
title("Five panels, with legend in a hole") ///
subtitle("Use -gr combine ... , having specified" ///
"-ring(0) pos(5) xoffset(40)- on the last panel") ///
name(grcomb5, replace)

(click to run Example 2.2)

Example 2.3: Example 2.3 demonstrates using gr combine to construct
a graph with eight panels and the legend in the middle.
In the above two examples there was no need to specify the
holes option, since the number of panels and the default panel layout assured there
would be a "hole" in the lower right hand corner of the array.
In this example, because we want the hole in the middle,
after the fourth panel, we must specify
holes(5).

Example 2.3: Using gr_combine with eight panels

gr combine panel1 panel2 panel1 panel0 panel1 panel2 panel1 panel2, ///
xcommon ycommon holes(5) ///
title("Ex. 2.3: Eight panels, with legend in the middle") ///
subtitle("Use -gr combine ... , having specified" ///
"-ring(0) pos(3) xoffset(40)- on graph for the fourth panel") ///
name(grcomb8, replace)

(click to run Example 2.3)

3.	Examples of a two-step procedure using grc1leg2

===============================================

In addition to allowing all the graph combine options, grc1leg2
allows the user to modify the combined graph in all the ways (a) through (m) listed
above.
The following examples demonstrate many of these capabilities,
without attention to the aesthetic or analytical quality of the result.
Hopefully users can use the tools described here to produce
visualizations which attain these qualities.
(For other examples, see the
do file entitled grc1test.do, available with this
//digital.cgdev.org/doc/stata/MO/Misc")"':package.)

Example 3.0: If starting here (without running Examples 1.1 and 1.2
and 2.1 - 2.3 above),
read and prepare the data by clicking
here,
and then create the component panel graphs (panel0, panel1, panel2 and panel3) by clicking
here.

Example 3.0: Using grc1leg2 without options

grc1leg2 panel0 panel1 panel2 panel3 , ///
title("Ex. 3.0: Four panels") ///
subtitle("Use -grc1leg2- to borrow the legend from panel0") ///
name(grc14dflt, replace)

(click to run Example 3.0)

Example 3.1: To display the single legend clearly,
leaving a "hole" somewhere in the layout
makes a place for the legend in that hole.
Example 3.1 demonstrates leaving the hole in the lower
right corner of the layout (in clock position 5).

Example 3.1: Using grc1leg2 to display three panels with their legend in a "hole"

grc1leg2 panel1 panel2 panel3, ///
ring(0) pos(5) ///
title("Ex. 3.1: Three panels, with legend in a hole") ///
subtitle("Use -grc1leg2- with options -ring(0) pos(5)- and" ///
"without the option -xtob1title-") ///
name(grc13woxtob1, replace)

(click to run Example 3.1)

In the above example, note that we can use the legend from
the named graph panel1 despite the legend's display having been suppressed
at the time of panel1's creation by the option legend(off).

Example 3.2: In the combined graph named grc3woxtob1 produced above by grc1leg2,
the options ring(0) and pos(5) provide insufficient
control of the legend's placement,
pushing the legend too far to the southeast.
By adding appropriately selected legend offsets, we can center
the legend in the middle of the "hole" in the southeast quadrant.

Example 3.2: Using grc1leg2 to center the combined legend in the "hole"

grc1leg2 panel1 panel2 panel3, ///
ring(0) pos(5) ///
lxoffset(-20) lyoffset(17) ///
title("Ex. 3.2: Three panels, with legend in a hole") ///
subtitle("Use -grc1leg2- with options -ring(0) pos(5)- and" ///
"fine-tuned with legend offset options") ///
name(grc13_offset, replace)

(click to run Example 3.2)

Example 3.3: Use of grc1leg2's xtob1title option in Example 3.3
saves additional space in the y-dimension
and reduces the excess "ink" in the graph by suppressing xtitles
on the individual panels and instead using a single overall b1title
for the entire combined graph.
The option ytol1title borrows the y-title from
one of the component graphs, saving space in the x-dimension.
Optionally use xcommon and/or ycommon to facilitate
comparison of adjacent panels.
(Example 3.9 shows how to replace redundant
titles on the right-hand y-axis with a single r1title on the combined graph.)

Example 3.3: Using grc1leg2 to suppress redundant axis titles

grc1leg2 panel1 panel2 panel3, ///
xcommon ycommon ring(0) pos(5) ///
lxoffset(-10) lyoffset(17) ///
title("Ex. 3.3: Three panels, with legend in a hole") ///
subtitle("Use -grc1leg2- with options -ring(0) pos(5)- " ///
"with the offset options plus -xtob1title- and -ytol1title-") ///
xtob1title ytol1title ///
name(grc13, replace)

(click to run Example 3.3)

Example 3.3_bis: Options are also available to suppress redundant main titles, subtitles or notes
from component panel graphs, so that they instead appear as
the main title, subtitle or note of the combined graph.
Example 3.3_bis shows how to move the main title and note
from the the graph -panel1_bis- to the combined graph.

Example 3.3_bis: Moving the main title and a note to the combined graph

twoway ///
(scatter mpg weight if qual==1, yaxis(1)) ///
(lfit mpg weight if qual==1), ///
title("Ex. 3.3_bis: Move main title and note to combined graph") ///
subtitle("Low Quality") ///
note("Source: Gibbon, Edward (1890) The Decline and Fall of the Roman Empire." ///
" London: F. Warne and Co.") ///
ytitle(Miles per gallon) ///
legend(col(1) off) ///
name(panel1_bis, replace)

grc1leg2 panel2 panel3 panel1_bis, ///
xcommon ycommon ring(0) pos(5) ///
lxoffset(-10) lyoffset(17) legendfrom(panel1_bis) ///
xtob1title ytol1title notetonote mainfrom(panel1_bis) notefrom(panel1_bis) ///
name(grc13_bis, replace)

(click to run Example 3.3_bis)

Example 3.4a: Use of the legscale(size)
option allows the user to increase the size of all elements
inside the legend box. However, in this case doing so
enlarges the scatter plot markers in the legend
to the extent that they no longer resemble
the markers in the component panels. To override the enlargement
of the markers, we add the option lmsize(*0.8)
to shrink the legend markers back until their size matches
their appearance in component panels.

Example 3.4a: Using grc1leg2 option legscale(size) to alter the size of all legend elements

grc1leg2 panel1 panel2 panel3, ///
xcommon ycommon ring(0) pos(5) ///
lxoffset(-6) lyoffset(14) ///
title("Ex. 3.4a: Three panels, with legend in a hole") ///
subtitle("Use -grc1leg2- with options -ring(0) pos(5)- " ///
"and with -legscale(*1.2) lmsize(*.8)-") ///
xtob1title ytol1title legscale(*1.2) lmsize(*.8) ///
name(grc13legscale, replace)

(click to run Example 3.4a)

Example 3.4b: An alternative approach to creating a similar legend is to
use the labsize(textsizestyle) and symxsize(size) options
to instead change the sizes of the labels and symbols inside the legend box,
overriding the default sizes.
By experimenting with various combinations of the legend and legend element
sizing options, it should be possible to achieve the desired effect
without resorting to the graph editor.

Example 3.4b: Using grc1leg2 to edit specific legend elements

grc1leg2 panel1 panel2 panel3, ///
xcommon ycommon ring(0) pos(5) ///
lxoffset(-6) lyoffset(14) ///
title("Ex. 3.4b: Three panels, with legend in a hole") ///
subtitle("Use -grc1leg2- with options -ring(0) pos(5)- and with the" ///
"offset, borrowed title, -labsize(*1.2)- and -symxsize(*1.2)- options") ///
xtob1title ytol1title labsize(*1.2) symxsize(*1.2) ///
name(grc13labsize, replace)

(click to run Example 3.4b)

Example 3.5: To position the legend in the middle of an eight-panel array,
we use the options -ring(0) pos(0) holes(5)-

Example 3.5: Using grc1leg2 to put a legend in the middle of eight panels

grc1leg2 panel1 panel2 panel3 panel2 panel3 panel2 panel3 panel2, ///
xcommon ycommon ring(0) pos(0) holes(5) ///
title("Eight panels: with legend in middle") ///
subtitle("Use -grc1leg2- with options -ring(0) pos(0) holes(5)- and" ///
"with the options -xtob1title- and -ytol1title-") ///
xtob1title ytol1title ///
name(grc18pnl, replace)

(click to run Example 3.5)

Example 3.6: When the graph array is rectangular, with four or six panels,
it may not be feasible or desirable to locate the common legend
inside the graph. In this case, when the legend must be located
on one of the margins of the multi-panel graph, the most
obvious alternatives are to leave the legend in its default location at
position(6) or to move it to the right margin with position(3).
However, position(6) conflicts with the option xtob1title
by putting the x-title below the legend.
The solution to using the option xtob1title with the legend at the bottom
of the combined graph is to use the option ring(2) instead
of the default ring(1). Furthermore, by using the legendfrom option
to select the legend from -panel2- that was created with one row and two columns,
the legend lies flat at the bottom of the combined graph.

Example 3.6: Using grc1leg2 to put the legend below the b1title

grc1leg2 panel0 panel1 panel2 panel3 , ///
xcommon ycommon ring(2) legendfrom(panel2) ///
title("Four panels: with legend at bottom") ///
subtitle("Use -grc1leg2- with options -ring(2) pos(6)- and" ///
"with the options -xtob1title- and -ytol1title-") ///
xtob1title ytol1title ///
name(grc14pnl, replace)

(click to run Example 3.6)

Example 3.7: Like its progenitor grc1leg, grc1leg2 is conceived as a utility
to add a legend to a composite graph made up of several panels.
Because a multi-panel graph is already complex, a user would rarely
want to further complicate its interpretation by including a panel which
itself consists of multiple panels. However, if the user does need to embed a previously
created multi-panel graph as one of several panels in a new multi-panel graph,
grc1leg2 can accommodate.

Example 3.7 shows that grc1leg2 can successfully find and relocate
the legend on a multi-panel graph created by graph, by().
Using the gr combine option altshrink helps the original titles
fit into the combined graph.

Example 3.7: Borrowing the legend from a graph created by -graph ..., by()-

grc1leg2 grby3 grcomb3, ///
title("Ex. 3.7: Relocating the legend from a by() graph") ///
altshrink ///
name(grc1fromby, replace)

(click to run Example 3.7)

Example 3.8: Similarly Example 3.8 shows that grc1leg2 can successfully find and relocate
the legend on a multi-panel graph created by graph combine.

Example 3.8: Borrowing the legend from a graph created by -graph combine-

grc1leg2 grcomb3 grby3, ///
title("Ex. 3.8: Relocating the legend from a combined graph") ///
altshrink ///
name(grc1fromcomb, replace)

(click to run Example 3.8)

To a limited degree grc1leg2, like gr combine, is recursive, accomodating graphs as input
that it has itself previously constructed. One could, for example,
combine the results of Examples 3.4b and 3.6 with a single legend borrowed from 3.4b like this:

grc1leg2 grc14pnl grc13labsize , altshrink ring(0) pos(5) lyoffset(20)

Or even like this:

grc1leg2 grc1fromby grc1fromcomb, altshrink

Example 3.9: When component panels of a combined graph have a y-axis on both the left and
the right side of the plot region, each of these two y-axes may have its own title.
The option y2tor1title directs grc1leg2 to suppress the redundant
titles on yaxis(2) of the component panels and relocate one of them to the
r1title of the combined graph.
Example 3.9 demonstrates this capability.
Also see example 3.3

Example 3.9: Relocating the titles on a second y-axis

set graph off
twoway ///
(scatter mpg weight if qual==1, yaxis(1)) ///
(scatter length weight if qual==1, yaxis(2)), ///
subtitle("Low Quality") ///
ylabel(,angle(hor) axis(2)) ///
name(panel4, replace)

twoway ///
(scatter mpg weight if qual==2, yaxis(1)) ///
(scatter length weight if qual==2, yaxis(2)), ///
subtitle("Medium") ///
ylabel(,angle(hor) axis(2)) ///
name(panel5, replace)

twoway ///
(scatter mpg weight if qual==3, yaxis(1)) ///
(scatter length weight if qual==3, yaxis(2)), ///
subtitle("High Quality") ///
ylabel(,angle(hor) axis(2)) ///
name(panel6, replace)
set graph on

grc1leg2 panel4 panel5 panel6, ///
title("Ex. 3.9: Relocating the title on yaxis(2)") ///
xtob1title ytol1title y2tor1title ///
pos(4) ring(0) lxoffset(-20) lyoffset(15) ///
name(grc1y2tor1, replace)

(click to run Example 3.9)

Examples 3.10a, 3.10b and 3.10c: grc1leg and grc1leg2 transfer the legend from one of several component graphs
to become the legend for the combined graph. But what if none of the legends of K component graphs includes
the keys from all of them? A solution to this problem is to create one
extra graph, the K+1st graph, with a legend containing the keys from all K of the component graphs.
Then we borrow the legend from this K+1st graph, but hide the actual K+1st graph.

Examples 3.10a, 3.10b and 3.10c show how this works. In Example 3.10a the three desired component graphs
are panel7, panel8, and panel9, each with a legend containing different keys.
So we create a fourth graph, called panel10,
which graphs all three y-axis variables against the common x-axis variable, weight.
By specifying the colors of the markers, symbols, labels
and fitted lines for all the component graphs, including the auxiliary graph (panel10),
we assure that the elements of the legend displayed by grc1eg2
match those in the displayed panels.
(For the purposes of this example, we ignore other possible approaches
such as measuring price in thousands of dollars or using a
second y-axis.)

Using grc1leg2's option legendfrom(graph_name), we specify that the combined legend
be borrowed from the component graph panel10, the last of the listed graph names.
Also specifying the option hidelegendfrom
instructs grc1leg2 to hide the unreadable graph from which the legend has been borrowed.
The space left by the hidden graph serves as the "hole" for the combined legend.
The option legend(colfirst cols(2) order(1 2 3 5 4) holes(3)) used to create panel10
organizes the legend elements so that all three panel9 markers are grouped
together in the second column, improving the legend's readability in the combined graph.
By default, grc1leg2 shrinks all elements of the legend by 30% using the option
legscale(*.7), allowing the two-column layout to fit within the available "hole".

Examples 3.10a, b and c: Assembling a composite legend using the hidelegendfrom option

set graph off

twoway ///
(scatter mpg weight, mcolor(blue)), ///
name(panel7, replace)

twoway ///
(scatter length weight, mcolor(red)), ///
name(panel8, replace)

twoway ///
(scatter price weight, mcolor(green)) ///
(lfitci price weight, lcolor(green)), ///
ytitle(Price) ///
name(panel9, replace)

twoway /// This is the component graph from which we take the legend
(scatter mpg weight, mcolor(blue)) ///
(scatter length weight, mcolor(red)) ///
(scatter price weight, mcolor(green)) ///
(lfitci price weight, lcolor(green)), ///
legend(colfirst cols(2) order(1 2 3 5 4) holes(3)) /// <- Avoids using the option -lcols()- of -grc1leg2-
name(panel10, replace)
set graph on

grc1leg2 panel7 panel8 panel9 panel10, ///
title("Ex. 3.10a: Assemble the legend keys from different panels" ///
"to construct the combined legend") ///
subtitle("Combining twoway graphs with different markers") ///
xtob1title legendfrom(panel10) hidelegendfrom ///
pos(4) ring(0) lyoffset(15) ///
name(grc1hide, replace)

(click to run Example 3.10a)

Example 3.10b: The same trick can be used to combine a graph without markers, such as by graph pie,
with a graph containing markers, such as scatter.
We cannot make an auxiliary graph with a legend containing both pie chart and scatter plot markers
by simply combining a pie chart with a scatter plot as we did with scatter plots above,
because graph twoway cannot make a pie chart.
Instead we use twoway rarea to mimic the pie chart legend's keys in an auxiliary graph named sym_and_mark.
To assure that the combined scatter plots in sctr_markers use the same colors
as the pie chart, we specify the pstyle options p1pie, p2pie and
p3pie for the scatter plots in sctr_markers and also in sym_and_mark.
To control the layout of the panels in the combined graph, list
the hidden graph, sym_and_mark, last among the graphs to be combined by grc1leg2.

set graph off

// The pie graph's legend has symbols.
graph pie, over(qual) plabel(_all percent, format(%5.1f) size(vlarge)) ///
name(pie_symbols, replace)

// The scatter plot's legend has markers.
tw (scatter price weight if qual==1, pstyle(p1pie) msym(Oh)) ///
(scatter price weight if qual==2, pstyle(p2pie)) ///
(scatter price weight if qual==3, pstyle(p3pie)), ///
name(sctr_markers, replace)

// The auxiliary graph needed for its legend has both symbols and markers
tw (rarea price price weight if qual==1) ///
(rarea price price weight if qual==2) ///
(rarea price price weight if qual==3) ///
(scatter price weight if qual==1, pstyle(p1pie) msym(Oh)) ///
(scatter price weight if qual==2, pstyle(p2pie)) ///
(scatter price weight if qual==3, pstyle(p3pie)), ///
legend( ///
label(1 "Low Quality") ///
label(2 "Medium Quality") ///
label(3 "High Quality") ///
label(4 "Low Quality") ///
label(5 "Medium Quality") ///
label(6 "High Quality") ///
rows(2) ///
) ///
name(sym_and_mark, replace)

set graph on

grc1leg2 pie_symbols sctr_markers sym_and_mark, ///
title("Ex. 3.10b: Assemble the legend keys from different panels" ///
"to construct the combined legend") ///
subtitle("Combining a graph with markers with a graph with color swatches") ///
legendfrom(sym_and_mark) hidelegendfrom ///
name(grc1hide2, replace)

(click to run Example 3.10b)

Example 3.10c: Excel includes a graph called a
"bar_of_pie" chart,
which is a combined graph
consisting of a pie chart with a highlighted or "exploded" slice and a bar chart
showing subcategories of the the exploded slice.
Example 3.10c demonstrates the construction of a bar_of_pie chart using -grc1leg2.
Hat tip to Fabio Tufano for suggesting this application of grc1leg2.

// Generate a discrete variable with three categories of foreign cars by country of manfacture
gen byte forcntry = 1 if foreign
replace forcntry = 2 if inlist(word(make,1),"VW", "BMW", "Audi")
replace forcntry = 3 if inlist(word(make,1),"Datsun", "Honda", "Mazda", "Toyota")

label define forcntry 1 "Other foreign" 2 "Germany" 3 "Japan"
label values forcntry forcntry

// The new categorical variable is defined only for foreign cars
tab forcntry foreign, mi

set graph off

// The big picture: Foreign as a share of all models in 1978
gr pie , over(foreign) angle(305) plabel(_all percent, size(large) format(%6.1f)) ///
subtitle(Shares of domestic and foreign models) ///
pie(1) pie(2, explode) ///
graphregion(margin(l -25) ) /// <- to prepare for landscape orientation
name(pie_dom_for, replace)

// Zoom in on the distribution of foreign models by country of origin
gr bar (percent), over(forcntry) asyvars stack yalternate ///
bar(1, bstyle(p3bar)) bar(2, bstyle(p4bar)) bar(3, bstyle(p5bar) ) ///
blabel(bar ,pos(center) size(large) format(%6.1f)) ///
graphregion(margin(r +25) ) fxsize(35) /// <- to prepare for landscape orientation
subtitle("Breakdown of foreign models") ///
name(bar_for, replace)

For the sole purpose of using its legend in the combined graph, we create a "dummy graph" with five legend keys.
Since we are only using the legend from this graph, we can use any five-category variable to construct the dummy graph.
-auto.dta- concidentally contains a five-category variable, -rep78-.
So we construct a pie chart over that variable to make a legend with five color swatches.
In order to spread the legend horizontally,
we use the option -holes(3/15)- to put three empty columns
in the middle of the legend.

// Construct the "dummy graph"
gr pie , over(rep78) ///
legend(colfirst cols(6) holes(3/15) ///
title("Location of manufacturer") ///
order( ///
1 "Domestic" ///
2 "Foreign" ///
5 "Japan" ///
4 "Germany" ///
3 "Other foreign" ///
) ) ///
name(pie_legend, replace)

set graph on

// -grc1leg2- allows us to apply the legend from the dummy graph to the combined graph
grc1leg2 pie_dom_for bar_for pie_legend, legendfrom(pie_legend) hidelegendfrom ///
title("Ex. 3.10c: Distribution of automobile models by domestic and foreign" ///
"and within foreign, by country of origin") ///
xsize(9) ysize(5) /// <- landscape orientation
name(bar_of_pie, replace)

(click to run Example 3.10c)

To more closely replicate the Excel "bar-of-pie" look, you may want to add arrows
from the exploded slice to the bar. grc1leg2 will not do this for you,
but it is easy to do with the graph editor. To see the result of such an edit,
as applied to the graph produced by Example 3.10c above, click on the next link.

(click to add arrows to the "bar of pie" graph)

Example 3.11: One way to change the overall "look" of a combined graph would be to carefully control
the look of each of the component graphs. Often, however, it is easier
or more effective to apply options to change the look of the combined graph without bothering
to change the look of the component graphs. Example 3.11 shows that
grc1leg2's gr_display_options borrowed from
graph display allow the user to override
some features of the individual graphs in favor of a common look for all the panels
of a combined graph.

Example 3.11: Changing the overall look of a combined graph

grc1leg2 panel1 panel2 panel3, ///
xcommon ycommon ring(0) pos(5) ///
lxoffset(-5) lyoffset(15) ///
xtob1title ytol1title ///
xsize(8) ysize(8) scheme(s1rcolor) /// <-- set the dimensions & scheme for this graph only
title("Example 3.11 is 3.3 with a different overall look") ///
subtitle("From the same component panels," ///
"alter the overall look of the combined graph" ///
"using the xsize(), ysize() and scheme() options") ///
name(grc13_dispopts, replace)

(click to run Example 3.11)

Example 3.12: grc1leg2's options lrows(integer) and lcols(integer) enable
the user to alter the row and column arrangement of the original borrowed legend.
However, when saving the combined file to disk, the user must specify the
saving sub-option asis to preserve the row and column rearrangement.
The changes made by all other grc1leg2 options save to disk without problem in a "live" gph file.
Example 3.12 shows that a saved "live" gph file
preserves all edits except the changed arrangement.
(See Issue #2 under "Known issues".)

Example 3.12: Change the legend's row and column arrangement and save to disk

grc1leg2 panel7 panel8 panel9 panel10, ///
title("Ex. 3.12: Change the legend's row and column arrangement" ///
`"with lcols(1) and save to disk as a "live" gph file"') ///
xtob1title legendfrom(panel10) hidelegendfrom ///
pos(4) ring(0) lxoffset(-5) lyoffset(15) lcols(1) ///
name(grc1lcols, replace) saving(grclcols, replace)

(click to run Example 3.12)
(click here to view the saved gph file)

Example 3.13: Example 3.13 demonstrates how to save the effects of options
lrows(integer) and lcols(integer) by using the sub-option asis
within grc1leg2's saving(saving_options).
However, a gph file saved "asis" is "frozen" and can no longer be edited
using Stata's graph editor. For this reason, if one wants to save a "live"
gph file, the preferred strategy is to avoid using grc1leg2's
lrows(integer) or its lcols(integer) option by arranging the rows and columns
in the component graph as in Example 3.10.

Example 3.13: Save the changed row and column arrangement with the option -asis-

grc1leg2 panel7 panel8 panel9 panel10, ///
title("Ex. 3.13: Change the legend's row and column arrangement" ///
`"with lcols(1) and save to disk as an "asis" gph file"') ///
xtob1title legendfrom(panel10) hidelegendfrom ///
pos(4) ring(0) lxoffset(-5) lyoffset(15) lcols(1) ///
name(grc1lcolsasis, replace) saving(grc1lcolsasis, replace asis)	// <-- Only change is to include the sub-option -asis-

(click to run Example 3.13)
(click here to view the saved gph file)

+

KNOWN ISSUES

Issue 1. grc1leg2 sometimes fails when the legend designated
for the combined graph is not "complete" or is otherwise unexpected or degenerate.
Starting with version 2.10, grc1leg2 attempts to detect these conditions and either
prevent them or exit politely with an informative error message. If you encounter
an error such as
series # not found,
class type not found or
class member function not found
(r(111),
r(4018) or
r(4023)),
please contact the
author.

Issue 2. The changes effected by using grc1leg2's lrows(integer) or lcols(integer) option
are not preserved when the displayed memory graph is saved to disk as a "live" gph file.
To preserve these changes in a saved file, the save must be performed with the
sub-option asis. See Examples 3.12 and 3.13

Reference

Cox, Nicholas J. (2020) "Stata tip 139: The by() option of graph can work better
than graph combine", The Stata Journal, Vol 20, Number 4, pp. 1016–1027.
https://journals.sagepub.com/doi/pdf/10.1177/1536867X20976341

Authors and acknowledgements

Vince Wiggins coded grc1leg and distributed it on Statalist 16 June 2003.
His version 1.0.5, dated 02jun2010, is available from
Stata.
grc1leg2 is a hack of his version 1.0.5. This help file builds on his
original help file for grc1leg, adding documentation
of grc1leg2's options and examples of Stata's alternative
approaches to control the placement of a single legend in a multi-panel
graph. In April 2016, Derek Wagner of StataCorps suggested code
to implement the -labsize(textsizestyle)- option.

Thanks to Statalist members Florian Schneider and Andrew Musau,
who found a bug I introduced in version 1.41 and led me
to identify the problem with some legend options which cause grc1leg2
to fail and to generate the error series # not found.
See the discussion of the problem as a known issue.

The addition of the gr_display_options in version 1.60 is in response
to a discussion on Statlist
here
and especially to
Jeff Pitlabo's
suggestion
that the aspect ratio of a combined graph could be changed in "post-production" by using graph display.

Version 2.0 responds to the suggestion of a Statalist member that grc1leg2
should allow the user to alter the size of the legend keys
and, by default, should shrink those keys for the combined
graph in order to preserve their resemblance to the keys in the component graphs.
To address these issues, this version adds the options legscale(size) and lmsize(size).
In implementing these changes, I discovered that the edits effected by many
previously introduced grc1leg2 options were not preserved
when the graph was saved using the option saving(saving_option).
This problem is now largely fixed. The exceptions are grc1leg2's
options lrow() and lcol(), the results of which are displayed
but not saved to a live gph file.
See Examples 3.12 and 3.13 for a work-around.

* Options marked with this asterisk
were part of grc1leg.

Contact Mead Over at MOver@CGDev.org or on Statalist
if you observe any problems and especially if you encounter difficulties with, or can suggest a solution for,
the known issues.