capture log close
set more off
graph drop _all
serset clear
cap prog drop grc1leg2
cap prog drop grc1leg2_examples
mata : mata clear

log using grc1test, replace

*	Updated 4Nov2023 to use version 2.26 of -grc1leg2- and its help file

clear
graph drop _all
set graph on

*************************************************************************************
*	This DO file demonstrates alternative approaches to adding a single 
*	legend to a Stata graph with several panels.

*	For each of three approaches to creating a multi-panel graph with a single legend,
*	this DO file first executes examples from  the help file, -grc1leg2.sthlp-, 
*	and then runs code for the two-panel versions not included in the help file.

*	By default, Stata's -pause- setting is -off-.
*		Removing the asterisk in front of the following command 
*		causes this DO file to pause after each constructed graph,
*		allowing the user to follow the narrative by reading
*		the comments associated with each graph.

*pause on

*************************************************************************************

cap prog drop pause_msg
prog def pause_msg 
	pause Type "q" to continue or "BREAK" to stop:
end
*        0.  Set up the data
*        ===================

grc1leg2_examples setup

*	For some two-panel graph examples, 
*	we need a dichotomous variable with only two values.
gen byte qual2 = 2*(rep78<=3)+3*(rep78>=4)
	lab value qual2 qual
	
*	Here's how -qual- and -qual2- compare
tab qual qual2	

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

*	Example 1.0 from -grc1leg2.sthlp-
grc1leg2_examples grby3dflt
	pause_msg

*	Example 1.1 from -grc1leg2.sthlp-
grc1leg2_examples grby3
	pause_msg

*	Example 1.2 from -grc1leg2.sthlp-
grc1leg2_examples grby5
	pause_msg

*	Example 1.3
*	(omitted from the help file for -grc1leg2-)

*	With only two panels, -graph twoway ..., by()- puts 
*	a common legend centrally spaced below the common xtitle.
*	Works well when the number of resulting panels is even.
twoway  ///
	(scatter mpg weight)  ///
	(lfit mpg weight),  ///
		by(qual2,  ///
			title("Ex. 1.3: Two panels using -twoway ..., by()-")  ///
			subtitle("With an even number of panels" "default legend placement at 6 o'clock is satisfactory") ///
		)  ///
	name(grby2_pos6, replace)
	pause_msg

*	Example 1.4 
*	(omitted from the help file for -grc1leg2-)

*	-graph twoway ..., by(,leg(ring(0) pos(0) at(2)))- 
*	can insert a common legend between two panels.
*	Only works if the -by variable- has exactly two values.
twoway  ///
	(scatter mpg weight)  ///
	(lfit mpg weight),  ///
		legend(col(1)) ///
		by(qual2,  ///
			cols(3) holes(2) legend(ring(0) pos(0) at(2)) ///
			title("Ex. 1.4: Two panels with legend in a hole")  ///
			subtitle( "-twoway ..., by(..., cols(3) holes(2) leg(ring(0) pos(0) at(2)))-" )  ///
		)  ///
	name(grby2_pos0, replace)
	pause_msg

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

*	Make four component graphs -panel0- ... -panel3-
*	These memory graphs are used here and 
*	also in demonstrating -grc1leg2- in section 3.
grc1leg2_examples make4panels
	pause_msg

*	Example 2.1 from -grc1leg2.sthlp-
grc1leg2_examples grcomb3
	pause_msg

*	Example 2.2 from -grc1leg2.sthlp-
grc1leg2_examples grcomb5
	pause_msg

*	Example 2.3 from -grc1leg2.sthlp-
grc1leg2_examples grcomb8
	pause_msg

*	Examples with -gr combine- using only two panels
*	(Examples 2.4, 2.5 and 2.6 are omitted from the help file for -grc1leg2-)
	
*	Example 2.4
*	(omitted from the help file for -grc1leg2-)	

gr combine panel1 panel2,  ///
	xcommon ycommon     ///
	title("Ex. 2.4: Two panels: -gr combine-, default")  ///
	name(grcomb2, replace) 
	pause_msg
	
*	To add a single legend to a combined graph made with -gr combine-,
*	one can choose among alternative versions of panel 2 with legends offset  
*	to appear where desired in the combined graph.
*	This approach requires fine tuning the offset values 
*	to get the most visually placement in the combined graph.

*	Example 2.5
*	(omitted from the help file for -grc1leg2-)	

*	This version of the second panel places the common legend below the combined graph
twoway  ///
	(scatter mpg weight if qual==2)  ///
	(lfit mpg weight if qual==2),  ///
		subtitle("Medium")  ///
		legend(ring(0) pos(0) xoffset(-35) yoffset(-40))  ///
		name(panel2_yoff, replace)

*	With the -imargin()- option creating space at the bottom of the combined graph,
*	a common legend can be attached to the two combined panels like this.
gr combine panel1 panel2_yoff,  ///
	xcommon ycommon imargin(5 5 15 5)     ///
	title("Ex. 2.5: Two panels: -gr combine-, legend below")  ///
	subtitle("Use -gr combine ..., imargin(5 5 15 5)- having specified"   ///
		"-ring(0) pos(0) xoffset(-35) yoffset(-40)- on the right-most graph") ///
	name(grcomb2_below, replace) 
	pause_msg

*	In Example 1.4 above, -gr ..., by()- inserts a common legend
*	between two panels by deploying the option -holes()-.
*	But the -holes()- option appears to have no effect on -gr combine- 
*	when it combines only two graphs.

*	Example 2.6
*	(omitted from the help file for -grc1leg2-)	

*	So in order to embed a single legend within the array of panels 
*	created by -gr combine-, one can instead overlay the legend as follows:

twoway  ///  This version overlays the common legend onto the combined graph
	(scatter mpg weight if qual==2)  ///
	(lfit mpg weight if qual==2),  ///
		subtitle("Medium")  ///
		legend(ring(0) pos(5) col(1) xoffset(-45) yoffset(5))  ///
		name(panel2_xoff, replace)

gr combine panel1 panel2_xoff,  ///
	xcommon ycommon     ///
	title("Ex. 2.6: Two panels: -gr combine-, legend overlaid")  ///
	subtitle("Fine tune legend placement in component graph -panel2_xoff-") ///
	name(grcomb2_onto, replace) 
	pause_msg


*    3.  Examples of a two-step procedure using grc1leg2
*        ===============================================

*	Example 3.0 from -grc1leg2.sthlp-

grc1leg2_examples grc4dflt
	pause_msg

*	Example 3.1 from -grc1leg2.sthlp-
grc1leg2_examples grc3woxtob1
	pause_msg

*	Example 3.2 from -grc1leg2.sthlp-
grc1leg2_examples grc3_offset
	pause_msg

*	Example 3.3 from -grc1leg2.sthlp-
grc1leg2_examples grc3
	pause_msg

*	Example 3.3_bis from -grc1leg2.sthlp-
*	Move a main -title- and/or a -note- from a component graph to the combined graph. 
grc1leg2_examples grc3_bis
	pause_msg

*	Example 3.4a from -grc1leg2.sthlp-
grc1leg2_examples grc3legscale
	pause_msg

*	Example 3.4b from -grc1leg2.sthlp-
grc1leg2_examples grc3labsize
	pause_msg

*	Example 3.5 from -grc1leg2.sthlp-
grc1leg2_examples grc8pnl
	pause_msg

*	Example 3.6 from -grc1leg2.sthlp-
grc1leg2_examples grc4pnl
	pause_msg

*	Example 3.7 from -grc1leg2.sthlp-
grc1leg2_examples grcfromby
	pause_msg

*	Example 3.8 from -grc1leg2.sthlp-
grc1leg2_examples grcfromcomb
	pause_msg

*	Example 3.9 from -grc1leg2.sthlp-
grc1leg2_examples grcy2tor1
	pause_msg

*	Example 3.10 from -grc1leg2.sthlp-
*		Ex. 3.10a: Combining twoway graphs with different markers 
grc1leg2_examples grchide
	pause_msg

*		Ex. 3.10b: Combining a graph with markers with a graph with color swatches
grc1leg2_examples grchide2
	pause_msg

*		Ex. 3.10c: Add arrows from the exploded slice to the bar
grc1leg2_examples bar_of_pie
	pause_msg

*		Ex. 3.10c: Creating an Excel-style bar_of_pie graph
grc1leg2_examples play_grec_on_Ex_3_10c
	pause_msg

*	Example 3.11 from -grc1leg2.sthlp-
grc1leg2_examples grc3_dispopts
	pause_msg

*	Example 3.12 from -grc1leg2.sthlp-
grc1leg2_examples grclcols
	pause_msg

*	Example 3.13 from -grc1leg2.sthlp-
grc1leg2_examples grclcolsasis
	pause_msg

*	Example 3.14
*	(omitted from the help file for -grc1leg2-)	

*	Examples with -grc1leg2- using only two panels
*		-grc1leg2-'s default resembles Example 2.5	
grc1leg2 panel1 panel2,  ///
	xcommon ycommon    /// 
	title("Ex. 3.14: Two panels: -grc1leg2-, legend below")  ///
	subtitle("Use -grc1leg2- with default legend options ")  ///
	name(grc2_below, replace)

	pause_msg
	
*	Example 3.15
*	(omitted from the help file for -grc1leg2-)	

*		With options ring(0) and pos(0), -grc1legs-'s 
*		graph resembles Example 2.6
grc1leg2 panel1 panel2,  ///
	xcommon ycommon ring(0) pos(0)    ///
	title("Ex. 3.15: Two panels: -grc1leg2-, legend overlaid")  ///
	subtitle("Use -grc1leg2- with options:"  ///
		"ring(0) pos(0) xtob1title ytol1title") /// 
	xtob1title ytol1title ///
	name(grc2_onto, replace)
	
*	-grc1leg2- inherits -gr combine-'s blindness to the -holes()- options 
*	when there are only two graphs being combined.	

	pause_msg
	
*	Executing the utility -displaygph- displays all or a subset 
*	of the memory graphs created in this DO file for easy review.
*	Execution time increases with the number of graphs to be displayed.

*	-displaygph- can be installed from CGD's Stata repository 
*  by typing "search displaygph" or clicking here:
di `"{stata `"view net describe displaygph, from("http://digital.cgdev.org/doc/stata/MO/Misc")"'}"'


*	If -displaygph- is already installed, click here 
*	to display the named memory graphs created by -grc1leg2-:
di "{stata displaygph grc1* , mem}"

*	Experiment with various legend(order()) options to see if -order()- can break -grc1le2-
*		Start with Example 3.10a, but keep only the ci
set graph off

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(order(4))  ///
		name(dummy_onlyci, replace)
	
set graph on

grc1leg2 panel7 panel8 panel9 dummy_onlyci,  ///
	title("Can -order()- break -grc1leg2-, ver. 2.25?")   ///
	subtitle("dummy_onlyci keeps only the symbol for the CI (key #4)")  ///
	xtob1title legendfrom(dummy_onlyci) hidelegendfrom  ///
	pos(4) ring(0) lyoffset(15)  ///
	name(ex_onlyci, replace)

*		Add lines of text inside -order()-
set graph off

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 - "Text line #1" - "Text line #2" 3 5 4 6) )  ///
		name(dummy_addtext, replace)
	
set graph on

grc1leg2 panel7 panel8 panel9 dummy_addtext,  ///
	title("Can -order()- break -grc1leg2-, ver. 2.25?")   ///
	subtitle("dummy_addtext adds text lines inside -order()-")  ///
	xtob1title legendfrom(dummy_addtext) hidelegendfrom  ///
	pos(4) ring(0) lyoffset(15)  ///
	name(ex_addtext, replace)

*	If -displaygph- is already installed, click here 
*	to display the named memory graphs created by -grc1leg2-:
di "{stata displaygph ex_* , mem}"

log close
view grc1test.smcl