Thanks to Kit Baum, a new package, twby, is now available on SSC. It is a prefix command for twoway graph, that creates a cross-tabulation of graphs. By aligning the graphs appropriately, one does not need to label each individual graph, so instead twby labels the columns at the top and the rows on the side. It automates the process described in (Buis & Weiss 2009) To install it, type in Stata ssc install twby
In its simplest form you just specify the two categorical variables that represent the rows and the columns of the table of graphs, followed by a colon, followed by the twoway graph that should appear in each cell. For example:

Most of the sub-options you would normally use in the by option can be specified in the twby prefix. So if we want to make this graph prettier, we could do something like so:

We could use twby to visualize a three way cross-tabulation in a way similar to (Cox 2016).

Buis, Maarten L. and Weiss, Martin (2009) "Stata Tip 81: A Table of Graphs", The Stata Journal, 9(4):643-647. https://doi.org/10.1177/1536867X0900900410
Cox, Nicholas J. (2016) "Speaking Stata: Multiple bar charts in tableform", The Stata Journal, 16(2): 491-510. https://doi.org/10.1177/1536867X1601600214
In its simplest form you just specify the two categorical variables that represent the rows and the columns of the table of graphs, followed by a colon, followed by the twoway graph that should appear in each cell. For example:
Code:
webuse auto2, clear set scheme s1color twby foreign rep78 : scatter price weight
Most of the sub-options you would normally use in the by option can be specified in the twby prefix. So if we want to make this graph prettier, we could do something like so:
Code:
// use more sensible units replace weight = 0.00045359237*weight label variable weight "Weight (tonnes)" replace price = price / 1000 label variable price "Price (1000s {c S|})" //create the graph twby foreign rep78, compact : /// scatter price weight, /// ylab(,angle(0)) xlab(1(.5)2)
We could use twby to visualize a three way cross-tabulation in a way similar to (Cox 2016).
Code:
// open example data sysuse nlsw88, clear // create the necessary categorical variables gen byte urban = c_city + smsa if !missing(c_city,smsa) label define urban 2 "central city" /// 1 "suburban" /// 0 "rural" label value urban urban label variable urban "urbanicity" gen byte marst = !never_married + married if !missing(never_married,married) label define marst 0 "never married" /// 1 "widowed/divorced" /// 2 "married" label value marst marst label var marst "marital status" gen byte edcat = cond(grade < 12, 1, /// cond(grade == 12, 2, /// cond(grade < 16, 3,4))) /// if !missing(grade) label variable edcat "education" label define edcat 1 "< highschool" /// 2 "highschool" /// 3 "some college" /// 4 "college" label value edcat edcat // the three way table we want to visualize bys edcat: tab urban marst, row nofreq // recreate that table as variables contract edcat marst urban, zero nomiss egen tot = total(_freq), by(urban edcat) gen perc = _freq / tot *100 // variables that helps display the numbers in the graph gen lab = strofreal(perc, "%5.0f") gen y = -5 // the graph twby urban marst , /// compact left xoffset(0.5) legend(off) /// title("Percentage in each marital status" /// "given education and urbanicity") : /// twoway bar perc edcat , /// xlab(1/4, val alt) yscale(range(0 75)) /// ylab(none) ytitle("") barw(.5) || /// scatter y edcat , /// msymbol(none) mlab(lab) mlabpos(0) mlabcolor(black)
Buis, Maarten L. and Weiss, Martin (2009) "Stata Tip 81: A Table of Graphs", The Stata Journal, 9(4):643-647. https://doi.org/10.1177/1536867X0900900410
Cox, Nicholas J. (2016) "Speaking Stata: Multiple bar charts in tableform", The Stata Journal, 16(2): 491-510. https://doi.org/10.1177/1536867X1601600214
Comment